1. 程式人生 > >[圖] 2 遍歷-DFS|BFS-遞迴與非遞迴

[圖] 2 遍歷-DFS|BFS-遞迴與非遞迴

鄰接表

// DFS
int visit[MAX_VERTEX_NUM];
void DFSUtil_AL(ALGraph G, int v) {
	ArcNode *p;
	visit[v]=1;
	Visit(G.vers[v].data);
	for (p=G.vers[v].firstarc; p; p=p->next)
		if (!visit[p->adjV])
			DFSUtil_AL(G, p->adjV);
}
void DFS_AL(ALGraph G) {
	int i;
	for (i=0; i<MAX_VERTEX_NUM; i++) {
		visit[
MAX_VERTEX_NUM] = 0; } for (i=0; i<G.vernum; ++i) { if (!visit[i]) DFSUtil_AL(G, i); } } // DFS非遞迴 void DFSTraverse_Nonrecurisve(ALGraph G) { int visit[maxSize]; int i,j; ArcNode *p; int stack[maxSize],top=-1; for (i=0; i<maxSize; i++) visit[i]=0; for (i=0; i<G.vernum; i++) { if (
visit[i]==0) { //沒有訪問過 //從它開始 top=-1; //清空棧 stack[++top]=i; //入棧 visit[i]=1; Visit(G.vers[i].data); //訪問 while (top!=-1) { //棧不空 j = stack[top]; //得出棧頂 //從j開始走 for (p=G.vers[j].firstarc; p; p=p->next) { if (!visit[p->adjV]) { //這條邊沒有訪問過 visit[p->adjV]=1;Visit(G.vers[p->
adjV].data); //訪問 stack[++top]=p->adjV; //從這個點繼續 break; } else //這條邊走過了,找下條邊 continue; } if (p==NULL) { //j的鄰邊走完了,返回上個結點,繼續往下走 --top; } } } } } // BFS void BFSUntil_AL(ALGraph G,int v) { ArcNode *p; int i; int queue[maxSize],front,rear; front=rear=0; queue[rear]=v; rear=(rear+1)%maxSize; //入佇列 while (front!=rear) { //佇列未滿 i=queue[front]; front=(front+1)%maxSize; //出佇列 //訪問i visit[i]=1; Visit(G.vers[i].data); //訪問i的鄰邊 for (p=G.vers[i].firstarc; p; p=p->next) { if (visit[p->adjV]==0) { queue[rear]=p->adjV; rear=(front+1)%maxSize; } } } } void BFS_AL(ALGraph G) { //BFS遍歷 int i; for (i=0; i<MAX_VERTEX_NUM; ++i) visit[i]=0; //初始化 for (i=0; i<G.vernum; i++) { if (visit[i]==0) {//沒有訪問過 BFSUntil_AL(G, i); } } }

完整程式碼

【鄰接表】

#include<stdio.h>
#include<stdlib.h>

#ifndef BASE
#define BASE
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int bool;
#endif

#define VertexType char //點型別
#define VRType int //邊型別
#define maxSize 20
void Visit(VertexType e) {
	printf("%c", e);
}

#define MAX_VERTEX_NUM 20
typedef enum{DG, UDG} GraphKind;
typedef struct ArcNode{
	int adjV; //邊指向的頂點
	VRType weight; //權重
	struct ArcNode *next;
}ArcNode; //邊
typedef struct VNode{
	VertexType data;
	ArcNode *firstarc;
}VNode, AdjList[MAX_VERTEX_NUM]; //頂點
typedef struct{
	GraphKind kind;
	int vernum,arcnum;
	AdjList vers; 
}ALGraph;


/*------------------------
 |7.14 建立有向圖的鄰接表|
 ------------------------*/
Status InitGraph_AL(ALGraph *pG) { //初始化
	int i;
	pG->arcnum = 0;
	pG->vernum = 0;
	for (i=0; i<MAX_VERTEX_NUM; ++i)
		pG->vers[i].firstarc = NULL; //VC++6.0中指標初始化為0xcccccccc
	return OK;
}
int LocateVex_AL(ALGraph G, VertexType e) { //定位值為e的元素下標
	int i;
	for (i=0; i<G.vernum; ++i) {
		if (G.vers[i].data == e) {
			return i;
		}
	}
	return -1;
}
Status CreateDG_AL(ALGraph *pG) { //建立有向圖的鄰接表
	//輸入規則:頂點數目->弧的數目->各頂點的資訊->各條弧的資訊
	int i,a,b;
	char tmp[MAX_VERTEX_NUM];
	char h,t;
	ArcNode *p, *q;

	InitGraph_AL(pG); //VC++6.0中指標初始化為0xcccccccc,如果不將指標初始化為NULL,會出錯
	//圖的型別
	pG->kind = DG;
	//頂點數目
	scanf("%d", &i); if (i<0) return ERROR;
	pG->vernum = i;
	//弧的數目
	scanf("%d", &i); if (i<0) return ERROR;
	pG->arcnum = i;
	//各頂點資訊
	scanf("%s", tmp);
	for (i=0; i<pG->vernum; ++i) pG->vers[i].data=tmp[i];
	//弧的資訊
	for (i=0; i<pG->arcnum; ++i) {
		scanf("%s", tmp);
		h = tmp[0]; t = tmp[2];
		a = LocateVex_AL(*pG, h);
		b = LocateVex_AL(*pG, t);
		if (a<0 || b<0) return ERROR;
		p = (ArcNode *)malloc(sizeof(ArcNode)); if (!p) exit(OVERFLOW);
		p->adjV=b;p->next=NULL;
		if (pG->vers[a].firstarc) { //已經有邊了
			for (q = pG->vers[a].firstarc; q->next; q=q->next) ; //找到最後一條
			q->next = p;
		} else { //第一條邊
			pG->vers[a].firstarc = p;
		}
	}
	return OK;
}

// DFS
int visit[MAX_VERTEX_NUM];
void DFSUtil_AL(ALGraph G, int v) {
	ArcNode *p;
	visit[v]=1;
	Visit(G.vers[v].data);
	for (p=G.vers[v].firstarc; p; p=p->next)
		if (!visit[p->adjV])
			DFSUtil_AL(G, p->adjV);
}
void DFS_AL(ALGraph G) {
	int i;
	for (i=0; i<MAX_VERTEX_NUM; i++) {
		visit[MAX_VERTEX_NUM] = 0;
	}
	for (i=0; i<G.vernum; ++i) {
		if (!visit[i])
			DFSUtil_AL(G, i);
	}
}
// DFS非遞迴
void DFSTraverse_Nonrecurisve(ALGraph G) {
	int visit[maxSize];
	int i,j;
	ArcNode *p;
	int stack[maxSize],top=-1;	
	for (i=0; i<maxSize; i++) visit[i]=0;

	for (i=0; i<G.vernum; i++) {
		if (visit[i]==0) { //沒有訪問過
			//從它開始
			top=-1; //清空棧
			stack[++top]=i; //入棧
			visit[i]=1; Visit(G.vers[i].data); //訪問
			while (top!=-1) { //棧不空
				j = stack[top]; //得出棧頂
				//從j開始走
				for (p=G.vers[j].firstarc; p; p=p->next) {
					if (!visit[p->adjV]) { //這條邊沒有訪問過
						visit[p->adjV]=1;Visit(G.vers[p->adjV].data); //訪問
						stack[++top]=p->adjV; //從這個點繼續
						break;
					} else //這條邊走過了,找下條邊 
						continue;
				}
				if (p==NULL) { //j的鄰邊走完了,返回上個結點,繼續往下走
					--top;
				}
			}
		}
	}
}
// BFS
void BFSUntil_AL(ALGraph G,int v) {
	ArcNode *p;
	int i;
	int queue[maxSize],front,rear;
	front=rear=0;

	queue[rear]=v; rear=(rear+1)%maxSize; //入佇列
	while (front!=rear) { //佇列未滿
		i=queue[front]; front=(front+1)%maxSize; //出佇列
		//訪問i
		visit[i]=1;
		Visit(G.vers[i].data);
		//訪問i的鄰邊
		for (p=G.vers[i].firstarc; p; p=p->next) {
			if (visit[p->adjV]==0) {
				queue[rear]=p->adjV;
				rear=(front+1)%maxSize;
			}
		}
	}
}
void BFS_AL(ALGraph G) { //BFS遍歷
	int i;
	for (i=0; i<MAX_VERTEX_NUM; ++i) visit[i]=0; //初始化

	for (i=0; i<G.vernum; i++) {
		if (visit[i]==0) {//沒有訪問過
			BFSUntil_AL(G, i);
		}
	}
}

int main() {
/*
6
11
ABCDEF
B,A
B,D
C,B
C,F
D,C
D,E
D,F
E,A
F,A
F,B
F,E
*/
	ALGraph G;

	CreateDG_AL(&G); 
	
	DFS_AL(G);printf("\n");
	DFSTraverse_Nonrecurisve(G);printf("\n");
	BFS_AL(G);printf("\n");

	return 0;
}