1. 程式人生 > >用鄰接表儲存有向圖實現的dfs和bfs

用鄰接表儲存有向圖實現的dfs和bfs

#include<iostream>
#include<stdlib.h>
#define MAX 20
using namespace std;
class ArcNode {
public:
	int adjvex; //儲存弧的終止位置
	ArcNode*nextarc;
};
class VNode {
public:
	char data;  //結點資訊
	ArcNode*firsarc;//第一個弧邊的地址
};
//定義圖的相關資訊
class Graph {
public:
	VNode Node[MAX];
	int arcnum;//弧邊的個數
		int vexnum;//定點的個數
};
//主函式相關內容
void dfs(Graph G, int v);
void bfs(Graph G);
int visited[MAX];//標記dfs的陣列,看有沒有被訪問過
int book[MAX]; //標記bfs的陣列,看有沒有被訪問過
int main()
{
	//儲存圖的相關資訊
	Graph G;
	int i;
	for (i = 1; i <= MAX; i++)
	{
		G.Node[i].firsarc = NULL;
	}
	cout << "輸入圖的結點個數和弧的個數\n";
	cin >> G.vexnum;
	cin >> G.arcnum;
	cout << "輸入各結點按順序編號下對應資訊:";
	for (i = 1; i <= G.vexnum; i++)
	{
		cin >> G.Node[i].data;
	}
	cout << "輸入弧的資訊\n";
	char start, end; //儲存弧的起始點,終止點
	int s, t;//儲存起始點,終止點的編號
	int j;
	ArcNode*ptr, *p;
	for (i = 1; i <= G.arcnum; i++)
	{
		cin >> start;
		
		cin >> end;
		
		getchar();
		for (j=1;j <= G.vexnum; j++)
		{
			if (start == G.Node[j].data)
				s = j;
			if (end == G.Node[j].data)
				t =j;
		}
		ptr=new ArcNode;
		ptr->adjvex = t;
		
		if (G.Node[s].firsarc == NULL)
		{
			G.Node[s].firsarc = ptr;
		}
		else
		{
			p = G.Node[s].firsarc;
			while (p->nextarc)       //注意這裡只能是p->nextarc,要不然,p=NULL再退出就沒有意義了
			{
				p = p->nextarc;
			}
			p->nextarc = ptr;
		}
		cout << "sss\n";
		
		ptr->nextarc = NULL;
	}
	/*//輸出檢查
	for (i = 1; i <= G.vexnum; i++)
	{
		cout << G.Node[i].data << endl;
		p=G.Node[i].firsarc;
		while (p) 
		{
			cout << "ppp\n";
			cout << p->adjvex << endl;
			p = p->nextarc;
		}
	}*/
	for(i=1;i<=G.vexnum;i++) //防止圖是不連通的圖 
	{
		if(visited[i]!=1)
		    dfs(G,i); 
          }
	cout << "\n";
	bfs(G);
	system ("pause");
	

	return 0;
}
void dfs(Graph G, int v)
{
	cout << G.Node[v].data;
	visited[v] = 1;
	ArcNode*p = G.Node[v].firsarc;
	while (p)
	{
		if (visited[p->adjvex] == 0)
			dfs(G, p->adjvex);
		else
			p = p->nextarc;
	}

}
void bfs(Graph G)
{
	//定義佇列,並且對佇列進行初始化
	char queue[MAX] = { '\0' };
	int front = 0, rear = 1, i, j;
	ArcNode*ptr;
	for (j = 1; j <= G.vexnum; j++)  //這是為了防止圖不是聯通的
	{
		if (book[j] != 1)
		{
			cout << G.Node[j].data;  //在其進佇列之前對其進行訪問輸出
			book[j] = 1;
			queue[rear++] = G.Node[j].data;
			//從定點開始,不斷進行出隊,輸出,將定點有關的終點入隊,直到佇列為空
			while (rear -1 != front)
			{
				for (i = 1; queue[front+1] != G.Node[i].data; i++);
				front++;
				ptr = G.Node[i].firsarc;
			
				while (ptr)
				{
					if (book[ptr->adjvex] != 1)
					{
						cout << G.Node[ptr->adjvex].data;
						book[ptr->adjvex] = 1;
						queue[rear++] = G.Node[ptr->adjvex].data;
					}
						
					ptr = ptr->nextarc;
				}
			}
		}
	}

}
dfs就是先訪問某個頂點,然後將與之相連的並且是未被訪問過的頂點進行遞迴呼叫(找尋該頂點需要一層迴圈) 同時為了防止出現不連通的情況,將呼叫DFS()時傳入的頂點進行一層迴圈(1~頂點數)遍歷 BFS用棧來實現,