1. 程式人生 > >鄰接表深度優先遍歷和廣度遍歷

鄰接表深度優先遍歷和廣度遍歷

迴圈 佇列標頭檔案:Queue.h

#ifndef QUEUE_H
#define QUEUE_H
#define MAXSIZE 20
typedef struct Node{
	int data[MAXSIZE];
	int front;
	int order;
}Queue;
void InitQueue(Queue *q); //初始化佇列
bool IsEmpty(Queue *q); //判斷佇列是否為空
void EnQueue(Queue *q,int Element); //進隊
void DeQueue(Queue *q,int *e); //出隊
#endif //QUEUE_H


佇列實現檔案:Queue.cpp

#include "Queue.h"
#include <string.h>
void InitQueue(Queue *q)
{
	q->front = q->order = 0;
	memset(q->data,-1,sizeof(int)*MAXSIZE);
}
bool IsEmpty(Queue *q)
{
	if(q->order == q->front)
		return true;
	return false;
}
void EnQueue(Queue *q,int Element)
{
	if((q->order + 1) % MAXSIZE == q->front)
		return;
	q->data[q->order] = Element;
	q->order = (q->order + 1) / MAXSIZE;
}
void DeQueue(Queue *q,int *e)
{
	if(q->order == q->front)
		return;
	*e = q->data[q->front];
	q->front = (q->front + 1) % MAXSIZE;
}


圖的遍歷的標頭檔案:Graph.h

#ifndef GRAPH_H
#define GRAPH_H
#define MAXVEX 10
#define MAXEDGE 10
typedef char VertexType;  //頂點的資料型別
typedef int EdgeType; //邊表權值的資料型別
typedef struct edge{ //邊表結點
	int AdjEdge;    //當前結點的下標值
	EdgeType weight; //邊表結點的權值
	struct edge* next; //邊表指標域,指向下一個邊表
}EdgeNode;
typedef struct vertexs{ //頂點
	VertexType data;		//頂點資料
	EdgeNode* next;  //頂點域,指向下一個邊表
}VertexNode,vertex[MAXVEX];
typedef struct graph{    //圖的鄰接表
	vertex vertexes;      //圖的頂點
	int NumVertexes,NumEdges; //圖的頂點數和邊數
}Graph;
void CreateGraph(Graph *G); //建立圖
void DFS(Graph *G,int i); //深度優先遍歷
void DFSTraverse(Graph *G); //用鄰接表深度優先遍歷圖
void BFSTraverse(Graph *G); //用鄰接表廣度優先遍歷圖
#endif //GRAPH_H


遍歷的實現檔案:

#include "Graph.h"
#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
bool visited[MAXVEX];
void CreateGraph(Graph *G)
{
	EdgeNode *e = NULL;
	printf("請輸入圖的頂點數和邊數:\n");
	scanf("%d%d",&G->NumVertexes,&G->NumEdges);
	printf("請輸入圖的頂點資訊:\n");
	for(int i = 0;i < G->NumVertexes;++i)
	{
		fflush(stdin);
		scanf("%c",&G->vertexes[i].data);
		G->vertexes[i].next = NULL;
	}
	for(int k = 0;k < G->NumEdges;++k)
	{
		printf("請輸入圖的邊的連線資訊(vi,vj)及權值:\n");
		e = (EdgeNode*)malloc(sizeof(EdgeNode));
		if(!e)
			exit(OVERFLOW);
		fflush(stdin);
		int i,j,w;
		scanf("%d%d%d",&i,&j,&w);
		e->AdjEdge = j;
		e->weight = w;
		e->next = G->vertexes[i].next;
		G->vertexes[i].next = e;
		//由於是無向圖所以存在反鏈現象
		e = (EdgeNode*)malloc(sizeof(EdgeNode));
		if(!e)
			exit(OVERFLOW);
		e->AdjEdge = i;
		e->weight = w;
		e->next = G->vertexes[j].next;
		G->vertexes[j].next = e;
	}
}
void DFS(Graph *G,int i)		//深度優先遍歷
{
	visited[i] = true;			//設定下標為I的頂點為已訪問
	printf("%c ",G->vertexes[i].data); //輸出頂點資訊
	EdgeNode* p = G->vertexes[i].next; //下一個邊表結點
	while(p)
	{
		if(!visited[p->AdjEdge]) //如果是未訪問的則遞迴
			DFS(G,p->AdjEdge);
		p = p->next;
	}
}
void DFSTraverse(Graph *G)
{
	for(int i = 0;i < G->NumVertexes;++i) //初始化每個頂點都未訪問過
		visited[i] = false;
	for(int i = 0;i < G->NumVertexes;++i) //選取一個未訪問的頂點,進行深度優先搜尋,
		if(!visited[i]) //如果是連通圖只執行一次
			DFS(G,i);
}
void BFSTraverse(Graph *G)
{
	Queue q;
	InitQueue(&q); //初始化佇列
	for(int i = 0;i < G->NumVertexes;++i) //設定所為頂點為未訪問
		visited[i] = false;
	for(int i = 0;i < G->NumVertexes;++i)
	{
		if(!visited[i]) //選取一個未訪問的頂點,如果圖是連通圖,則只執行一次
		{
			visited[i] = true; //設定頂點為已訪問
			printf("%c ",G->vertexes[i].data); 
			EnQueue(&q,i); //當前頂點的下標值進隊
			while(!IsEmpty(&q)) //佇列不為空
			{
				DeQueue(&q,&i); //出隊
				EdgeNode *p = G->vertexes[i].next; //指向下一個邊表結點
				while(p)
				{
					if(!visited[p->AdjEdge]) //如果是未訪問的結點
					{
						visited[p->AdjEdge] = true;
						printf("%c ",G->vertexes[p->AdjEdge].data);
						EnQueue(&q,p->AdjEdge);
					}
					p = p->next; //指向下一個邊表結點
				}
			}

		}
	}
}


測試檔案:main.cpp

#include "Graph.h"
#include <stdio.h>
int main()
{
	Graph G;
	CreateGraph(&G);
	printf("深度優先搜尋遍歷:\n");
	DFSTraverse(&G);
	printf("\n");
	printf("廣度優先搜尋遍歷:\n");
	BFSTraverse(&G);
	return 0;
}