鄰接表深度優先遍歷和廣度遍歷
阿新 • • 發佈:2019-01-23
迴圈 佇列標頭檔案: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;
}