實驗項目六 圖結構基本操作的實現

實驗項目六 圖結構基本操作的實現(截止12-20)

實驗目的:

1.掌握圖的基本操作—遍歷。

實驗要求:

1、    分別用DFS和BFS的方法實現一個無向圖的遍歷。

實驗過程:

1、    創建一個圖(可用鄰接矩陣或鄰接表的方式進行存儲);

2、    輸入選項:0或1,0爲DFS,1爲BFS。

3、    分別輸出DFS和BFS兩種遍歷序列;

實驗報告中給出DFS和BFS兩種遍歷的算法代碼。

實驗結果:

1、輸入頂點集:1 2 3 4 5 6 7 8

2、輸入邊的集合: 1  2

1  3

2  4

2  5

4  8

5  8

3  6

3  7

6  7

輸入:0(DFS)

輸出:DFS遍歷序列爲:12485367

輸入:1(BFS)

輸出:BFS遍歷序列爲:12345678

實驗分析:

1.簡單分析DFS與BFS實現時用到的方法(DFS通過遞歸函數實現,用到棧的數據結構,BFS用到隊列的數據結構);

2.列舉調試運行過程中出現的錯誤並分析原因。

要求:

(1) 程序要添加適當的註釋,程序的書寫要採用縮進格式

(2) 程序要具在一定的健壯性,即當輸入數據非法時,程序也能適當地做出反應。

(3) 程序要做到界面友好,在程序運行時用戶可以根據相應的提示信息進行操作。

(4) 上傳源程序到課堂派。順序表的源程序保存爲TraversalGraph.cpp

#include <stdio.h>
#include <iostream>
#include <algorithm>
#define MaxInt 32767
#define MVNum 100
#define OK 1
#define ERROR 0

using namespace std;

typedef int Status;


//------隊列的鏈式存儲結構------- 
typedef struct QNode  
{
	int data;
	struct QNode *next;
}QNode,*QueuePtr;
 

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;


//鏈式隊列的初始化 
Status InitQueue(LinkQueue &Q)
{
	Q.front=Q.rear=new QNode;
	Q.front->next=NULL;
	return OK;
}


//鏈式隊列的入隊操作
Status EnQueue(LinkQueue &Q,int e)
{
	QueuePtr p;
	p=new QNode;
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
	return OK;
}		

//判斷隊列是否爲空
QueueEmpty(LinkQueue Q)
{
	if(Q.front==Q.rear) return OK;
	else return ERROR;	
} 


//鏈隊的出隊
Status DeQueue(LinkQueue &Q,int &e)
{
	QueuePtr p;
	if(Q.front==Q.rear) return ERROR;
	p=Q.front->next;
	e=p->data;
	Q.front->next=p->next;
	if(Q.rear==p) Q.rear=Q.front;
	delete p;
	return OK;	
}

//圖的鄰接矩陣存儲 
typedef int VerTexType;
typedef int ArcType;
typedef struct
{
	VerTexType vexs[MVNum];
	ArcType arcs[MVNum][MVNum];
	int vexnum,arcnum;
}AMGragh;

typedef AMGragh Gragh;

bool visited[MVNum];

//確定頂點在G中的位置
int LocateVex(AMGragh G,int m)
{
	return m-1;	
} 

//鄰接矩陣創建無向網
Status CreateUDN(AMGragh &G)
{
	int i,j,k;
	int v1,v2;
	printf("請輸入頂點數和邊數(空格隔開):");
	cin>>G.vexnum>>G.arcnum;
	for(i=0;i<G.vexnum;i++) 
	{
		printf("請輸入第%d個頂點的信息:",i+1);
		cin>>G.vexs[i];
	} 
	for(i=0;i<G.vexnum;i++)
	{
		for(j=0;j<G.vexnum;j++)
		{
			G.arcs[i][j]=0;
		}
	}
	for(k=0;k<G.arcnum;k++)
	{
		printf("請輸入一條邊依附的頂點(請用空格隔開):");
		cin>>v1>>v2;
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		G.arcs[i][j]=1;
		G.arcs[j][i]=G.arcs[i][j];
	}
	
	return OK;
} 

void DFS_AM(AMGragh G,int v)
{
	cout<<v;
	visited[v]=true;
	for(int w=0;w<G.vexnum;w++) 
		if((G.arcs[v-1][w]!=0)&&(!visited[w+1]))	
			DFS_AM(G,w+1);
} 

//尋找v1的第一個鄰接點
int FirstAdjVex(Gragh G,int v1)
{
	for(int i=0;i<G.vexnum;i++)
	{
		if(G.arcs[v1-1][i]==1&&!visited[i+1])
		{
			return i+1;	
		}	
	}
	
	return -1;	
} 

//u相對於w的下一個鄰接點
int NexAdjVex(Gragh G1,int u1,int w1)
{
	for(int i=0;i<G1.vexnum;i++)
	{
		if(G1.arcs[u1-1][i]==1&&(i+1)!=w1&&!visited[i+1])
		{
			return i+1;	
		}	
	}
	
	return -1;	
} 

void BFS(Gragh G,int v)
{
	LinkQueue Q;
	cout<<v;
	visited[v]=true;
	InitQueue(Q);
	EnQueue(Q,v);
	while(!QueueEmpty(Q))
	{
		int u;
		DeQueue(Q,u);
		for(int w=FirstAdjVex(G,u);w>=0;w=NexAdjVex(G,u,w))
		{
			if(!visited[w])
			{
				cout<<w;
				visited[w]=true;
				EnQueue(Q,w);	
			}	
		}	
	}	
} 

int main()
{
	AMGragh G;
	CreateUDN(G);
	bool choose; 
	printf("如果你想要使用DFS遍歷請輸入0,如果你想要使用BFS遍歷輸入1:");
	cin>>choose;
	if(choose==0) DFS_AM(G,1);
	else BFS(G,1);
	
	return 0;	
}

/*輸入緩存!當有多個輸入進入時,如果不小心多輸入,有可能會造成錯誤,使得多輸入的數據進入輸入緩存區
進而造成程序錯誤,避免這種情況的方法是:1、相同類型元素儘可能分開輸入2、相同類型數據的話,輸入一個數據後換行輸入另一個數據
一開始輸入頂點的時候8個頂點卻輸成了9個,結果第9個頂點進入緩存區,讀取成了v1,最後結果錯誤 
我們輸入的字符先存放在緩衝區,等按下回車鍵換行時才進行實際讀取操作
從本質上講,我們從鍵盤輸入的數據並沒有直接交給 scanf(),而是暫時保存到緩衝區中,直到我們按下回車鍵,scanf() 才從緩衝區中讀取數據,賦值給變量。如果緩衝區中的數據符合 scanf() 的要求,那麼就讀取結束;如果不符合要求,那麼就繼續等待用戶輸入,或者乾脆讀取失敗。scanf() 匹配到想要的數據後,會將匹配到的數據從緩衝區中刪除,而沒有匹配到的數據仍然會留在緩衝區中。

正是由於緩衝區的存在,才使得我們能夠多輸入一些數據,或者一次性輸入所有數據。
2、因爲下標問題,鄰接矩陣中的邊是從下標0開始存的,而bfs輸出頂點的時候是從1開始的,因此造成了一些錯誤。
3、沒有認真思考程序的每一行代碼,原本數據類型是int類型,自己直接抄的書上的代碼結果把數據定義成了char類型 
*/ 

這是我自己寫的!這是我自己寫的!這是我自己寫的!

開心的事要說三遍。在寫鄰接矩陣的時候,耐心的數據結構老師認真給我解答了疑惑,之後經過兩個半小時以上的努力,我終於寫完了這個程序。這對我來說是意義重大的,慾望的折磨、學習狀態的悽慘、個別人的嘲笑,讓我處於既努力自信又痛苦的尷尬境地之中,能夠獨立完成這個在周圍人看來不太簡單的任務,帶給我很大的快樂,那些不如意,此時又算得了什麼呢?

數據結構真的真的真的很簡單,不會的人可以問問自己,自己真的認真學了嗎?

我也逐漸懂得,只有學習、只有經過努力拿到不那麼容易拿到的東西,才能真正給你帶來快樂。那些容易得到的,大多隻是虛幻無意義的快感罷了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章