1. 程式人生 > >圖的鄰接表的遍歷(DFS(遞迴,非遞迴),BFS,拓撲排序)

圖的鄰接表的遍歷(DFS(遞迴,非遞迴),BFS,拓撲排序)

要求:對有向圖進行DFS(深度優先遍歷)、BFS(廣度優先遍歷)、拓撲排序。寫出深度優先遍歷的遞迴和非遞迴演算法。

程式碼如下:

在此非常感謝crazy_27的評論,給我指出錯誤。

#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <string.h>
#define MAX 100
using namespace std;

int visited[MAX+1];		//記錄是否訪問過 

typedef struct node{
	int data;
	struct node *next;
}Node,*ArcNode;
//定義鄰接表的邊型別 

typedef struct vnode{
	char data;
	ArcNode firstarc;
}VNode;
//定義鄰接表的結點型別 

typedef struct Graph{
	VNode AdjList[MAX];
	int vexnum,arcnum;
}MGraph;
//定義圖型別 

int LocateVex(char ch,MGraph G)
{//取該結點在陣列中的位置 
	int i;
	for(i=0;i<G.vexnum;i++)
		if(G.AdjList[i].data==ch)
			return i;
	return -1;
}

void InitGraph(MGraph &G)
{//建立一個有向圖 
	int n,m;
	int i,j,k;
	char ch1,ch2;
	ArcNode p;
	printf("請輸入結點個數和邊個數:");
	scanf("%d %d",&G.vexnum,&G.arcnum);
	printf("請輸入結點:");
	getchar();
	for(i=0;i<G.vexnum;i++)
	{
		scanf("%c",&G.AdjList[i].data);
		G.AdjList[i].firstarc=NULL;
	}
	
	printf("請輸入邊:");
	for(k=0;k<G.arcnum;k++)
	{
		getchar();
		scanf("%c %c",&ch1,&ch2);
		i=LocateVex(ch1,G);j=LocateVex(ch2,G);
		
		ArcNode e;
		e=(ArcNode)malloc(sizeof(Node));
		e->data=j;
		e->next=NULL;
		p=G.AdjList[i].firstarc;
		if(!p)
			G.AdjList[i].firstarc=e;
		else
		{
			while(p->next)
				p=p->next;
			p->next=e;
		}
	}
}


void DFS(MGraph G,int i)
{//深度優先搜尋遞迴演算法 
	ArcNode p;
	visited[i]=1;
	printf("%c ",G.AdjList[i].data);
	p=G.AdjList[i].firstarc;
	while(p)
	{
		if(!visited[p->data])
			DFS(G,p->data);
		p=p->next;
	}
}

void BFS(MGraph G)
{//廣度優先搜尋 
	queue<int>q;
	int i,j;
	ArcNode p;
	for(i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
		{
			visited[i]=1;
			q.push(i);
			printf("%c ",G.AdjList[i].data);
			while(!q.empty())
			{
				p=G.AdjList[q.front()].firstarc;
				while(p)
				{
					if(!visited[p->data])
					{
						visited[p->data]=1;
						printf("%c ",G.AdjList[p->data].data);
						q.push(p->data);
					}
					p=p->next;
				}
				q.pop();
			}
		}
	}
}

void DFSsearch(MGraph G)
{//深度優先搜尋非遞迴演算法 
	int i,j;
	stack <int>s;
	ArcNode p;
	memset(visited,0,sizeof(visited));
	for(i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
		{
			visited[i]=1;
			printf("%c ",G.AdjList[i].data);
			s.push(i);
			
			p=G.AdjList[i].firstarc;
			while(!s.empty())
			{
				while(p)
				{
					if(!visited[p->data])
					{
						visited[p->data]=1;
						printf("%c ",G.AdjList[p->data].data);
						s.push(p->data);
						p=G.AdjList[p->data].firstarc;
					}
					else
						p=p->next;
				}
				p=G.AdjList[s.top()].firstarc;
				s.pop();
			}
		}
	}
	putchar('\n');
}

void FindInDegree(MGraph G,int *indegree)
{
	int i;
	ArcNode p;
	for(i=0;i<G.vexnum;i++)
	{
		p=G.AdjList[i].firstarc;
		while(p)
		{
			indegree[p->data]++;
			p=p->next;
		}
	}
}

int TopologicalSort(MGraph G)
{
	int indegree[MAX]={0};
	int i,j,k;
	FindInDegree(G,indegree);
	
	stack <int>s;
	
	ArcNode p;
	for(i=0;i<G.vexnum;i++)
	{
		if(!indegree[i])
			s.push(i);
	}
	
	int count=0;
	
	while(!s.empty())
	{
		i=s.top();
		s.pop();
		printf("%c ",G.AdjList[i].data);
		count++;
		for(p=G.AdjList[i].firstarc;p;p=p->next)
		{
			k=p->data;
			if(!(--indegree[k]))
				s.push(k);
		}//for
	}//while
	if(count<G.vexnum)
		return 0;
	else
		return 1;
}

int main()
{
	int i,K;
	MGraph G;
	InitGraph(G);
	
	memset(visited,0,sizeof(visited));
	
	ArcNode p;
	p=G.AdjList[0].firstarc;
//	while(p)
//	{
//		printf("%c ",G.AdjList[p->data].data);
//		p=p->next;
//	}
//	putchar('\n');
	
	printf("深度優先搜尋的遞迴遍歷:"); 
	for(i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
			DFS(G,i);
	}
	putchar('\n');
	memset(visited,0,sizeof(visited));
	printf("廣度優先搜尋的遍歷:"); 
	BFS(G);
	putchar('\n');

	printf("深度優先搜尋的非遞迴遍歷:"); 
	DFSsearch(G);
	//拓撲排序
	printf("拓撲排序序列為:");
	K=TopologicalSort(G);
	if(K)
		printf("\n該圖是個有向無環圖\n");
	else
		printf("\n該圖是個有環圖\n") ;
	//判斷是有向無環圖
		
	return 0;
}




輸入示例:

8 8
ABCDEFGH
A B
B D
B E
D H
E H
A C
C F
C G

輸出示例:

深度優先搜尋的遞迴遍歷:

A B D H E C F G

廣度優先搜尋的遍歷:

A B C D E F G H

深度優先搜尋的非遞迴遍歷:

A B D H E C F G

拓撲排序序列為:

A C G F B E D H

該圖是個有向無環圖

圖例如下: