圖的鄰接表的遍歷(DFS(遞迴,非遞迴),BFS,拓撲排序)
阿新 • • 發佈:2019-01-27
要求:對有向圖進行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
該圖是個有向無環圖
圖例如下: