1. 程式人生 > >無向圖的鄰接矩陣,深度優先遍歷廣度優先遍歷的遞迴與非遞迴演算法

無向圖的鄰接矩陣,深度優先遍歷廣度優先遍歷的遞迴與非遞迴演算法

/*(1)輸入一組頂點,建立無向圖的鄰接矩陣。
進行DFS(深度優先遍歷)和BFS(廣度優先遍歷)。
寫出深度優先遍歷的遞迴和非遞迴演算法。*/
#include<stdio.h>
#define max 40  //最大頂點個數
#define M 10000 //無窮 
#include<stdlib.h>
typedef struct ArcCell{
	int adj;  //1/0表示是否有邊。網中表示權值 
}ArcCell,AdjMatrix[max][max];
typedef struct{
	char vexs[max]; //頂點表
	AdjMatrix arcs; //矩陣表 
	int vexnum,arcnum; //頂點數和邊數 
}MGraph;
typedef struct QNode{
	int data;
	struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
int InitQueue(LinkQueue &Q){
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)
		exit(0);
	Q.front->next=NULL;
	return 1;
}
int QueueEmpty(LinkQueue Q){
	if(Q.front==Q.rear)
		return 1;
	else
		return 0;
}
int EnQueue(LinkQueue &Q,int e){
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
	if(!p) exit(0);
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
	return 1;
}
int DeQueue(LinkQueue &Q,int &e){
	QueuePtr p;
    if(Q.front==Q.rear)
		return 0;
	p=Q.front->next;
	e=p->data;
	Q.front->next=p->next;
	if(Q.rear==p)
		Q.rear=Q.front;
	free(p);
	return 1;
}
int Locatevex(MGraph G,char v){
	int i; 
	for(i=0;i<G.vexnum;i++){
		if(G.vexs[i]==v)
			return i;
	}
}
void GreatGraph(MGraph &G){
	//建立無向圖G的鄰接矩陣
	int i,j,k;
	char v1,v2;
	printf("輸入頂點數和邊數:");
	scanf("%d%d",&G.vexnum,&G.arcnum);
	getchar();
	printf("輸入頂點的資訊:\n");
	for(i=0;i<G.vexnum;i++){
		scanf("%c",&G.vexs[i]);
	}
	//初始化矩陣 
	for(i=0;i<G.vexnum;i++){
		for(j=0;j<G.vexnum;j++){
			G.arcs[i][j].adj=0;
		}
	} 
	getchar();
	printf("輸入邊:\n");
	for(k=0;k<G.arcnum;k++){
		scanf("%c%c",&v1,&v2);
		getchar();
		i=Locatevex(G,v1);
		j=Locatevex(G,v2);
		G.arcs[i][j].adj=G.arcs[j][i].adj=1;
	}  
} 
int FirstAdjvex(MGraph G,int v){
	//查詢第一個鄰接點
	int j;
	for(j=0;j<G.vexnum;j++){
		if(G.arcs[v][j].adj==1)
			return j;
		else 
			return -1;
	}	
}
int NextAdjvex(MGraph G,int v,int w){
	//查詢下一個鄰接點
	int j;
	for(j=w+1;j<G.vexnum;j++){
		if(G.arcs[v][j].adj==1)
			return j;
		else
			return -1;
	} 
}
void PrintGraph(MGraph G){
	//按鄰接矩陣方式輸出無向圖 
	int i,j;     
	for(i=0;i<G.vexnum;i++){ 
		printf("%10c",G.vexs[i]);      
		for(j=0;j<G.vexnum;j++)         
 			printf("%4d",G.arcs[i][j].adj);      
		printf("\n");    
	} 
}
int visited1[max];
void Dfs(MGraph G,int v){
	 int j;
	 visited1[v]=1;
	 printf("%c",G.vexs[v]);
	 for(j=0;j<G.vexnum;j++){
	 	if(!visited1[j]&&G.arcs[v][j].adj!=0)
	 		Dfs(G,j);
	 }	
}
void DfsTraverse(MGraph G){
	//深度優先遍歷遞迴演算法 
	int v;
	for(v=0;v<G.vexnum;v++){
		visited1[v]=0;
	} 
	for(v=0;v<G.vexnum;v++){
		if(!visited1[v])
			Dfs(G,v);
	}	
} 
void DfsTraverse2(MGraph G){
	//深度優先遍歷非遞迴演算法 
	int visited2[max];
	int v,u,w; 
	LinkQueue Q;
	for(v=0;v<G.vexnum;v++)
		visited2[v]=0;
	InitQueue(Q);
	for(v=0;v<G.vexnum;v++)
		if(!visited2[v]){
			visited2[v]=1;
			printf("%c",G.vexs[v]); 
			EnQueue(Q,v);
			while(!QueueEmpty(Q)){
				DeQueue(Q,u);
				for(w=FirstAdjvex(G,u);w>=0;w=NextAdjvex(G,u,w))
					if(!visited2[w]){
						visited2[w]=1;
						printf("%c",G.vexs[w]);
						EnQueue(Q,w);
					}	
		    }
	    }
} 
void BfsTraverse(MGraph G){
	//廣度優先遍歷
	int visited3[max];
	int v,u,w; 
	LinkQueue Q;
	for(v=0;v<G.vexnum;v++)
		visited3[v]=0;
	InitQueue(Q);
	for(v=0;v<G.vexnum;v++)
		if(!visited3[v]){
			visited3[v]=1;
			printf("%c",G.vexs[v]);
			EnQueue(Q,v);
			while(!QueueEmpty(Q)){
				DeQueue(Q,u);
				for(w=0;w<G.vexnum;w++)
					if(!visited3[w]&&G.arcs[u][w].adj!=0){
						visited3[w]=1;
						printf("%c",G.vexs[w]);
						EnQueue(Q,w);
					}	
		    }
	    }
} 
int main(){
	MGraph G;
	GreatGraph(G);
	PrintGraph(G);
	printf("\nDfs(遞迴):");
	DfsTraverse(G);
	printf("\nDfs(非遞迴):");
	DfsTraverse2(G);
	printf("\nBfs:");
	BfsTraverse(G);
	return 0;
}