圖——鄰接表表示(實現深度優先遍歷、廣度優先遍歷)
阿新 • • 發佈:2019-02-09
程式碼有部分解析:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<iomanip> using namespace std; #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define MAX_VERTEX_NUM 20//最大頂點個數 typedef int Status; typedef int InfoType; typedef char VertexType; bool visited[MAX_VERTEX_NUM]; typedef struct ArcNode { int adjvex;//該弧所指向的頂點位置 struct ArcNode *nextarc;//指向下一條弧的指標 InfoType info;//該弧相關資訊的指標 }ArcNode; typedef struct VNode { VertexType data;//頂點資訊 ArcNode *firstarc;//指向第一條依附該頂點的弧的指標 }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; int vexnum, arcnum;//圖的當前頂點數和弧數 int kind;//圖的種類標誌 }ALGraph; int LocateVex(ALGraph G, char v) { int i; for (i = 0; i < G.vexnum; i++) { if (G.vertices[i].data == v) return i; } return -1; } /* 採用鄰接表儲存表示,構造無向圖G */ Status CreateUDG(ALGraph &G) { int i, j, k, IncInfo; ArcNode *pi, *pj; char v1, v2; cout << "輸入頂點數G.vexnum:"; cin >> G.vexnum; cout << "輸入邊數G.arcnum:"; cin >> G.arcnum; getchar(); for (i = 0; i < G.vexnum; ++i) { cout << "輸入頂點G.vertices[" << i << "].data:"; cin >> G.vertices[i].data; getchar(); //初始化連結串列頭指標為空 G.vertices[i].firstarc = NULL; } /* 輸入各邊並構造鄰接表 */ for (k = 0; k < G.arcnum; ++k) { cout << "請輸入第" << k + 1 << "條邊的兩個頂點:"<<endl; //輸入一條邊的起點和終點 cin >> v1; cin >> v2; getchar(); //確定V1和V2在G中的位置 i = LocateVex(G, v1); j = LocateVex(G, v2); if (!(pi = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 pi->adjvex = j; pi->info = 0; //插入連結串列G.vertices[i] pi->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = pi; if (!(pj = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 //插入連結串列G.vertices[j] pj->adjvex = i; pj->info = 0; pj->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = pj; }//for return OK; }//CreateUDG //有向圖 Status CreateDG(ALGraph &G) { int i, j, k, IncInfo; ArcNode *pi, *pj; char v1, v2; cout << "輸入頂點數G.vexnum:"; cin >> G.vexnum; cout << "輸入邊數G.arcnum:"; cin >> G.arcnum; getchar(); for (i = 0; i < G.vexnum; ++i) { cout << "輸入頂點G.vertices[" << i << "].data:"; cin >> G.vertices[i].data; getchar(); //初始化連結串列頭指標為空 G.vertices[i].firstarc = NULL; } /* 輸入各邊並構造鄰接表 */ for (k = 0; k < G.arcnum; ++k) { cout << "請輸入第" << k + 1 << "條邊的兩個頂點:" << endl; //輸入一條邊的起點和終點 cin >> v1; cin >> v2; getchar(); //確定V1和V2在G中的位置 i = LocateVex(G, v1); j = LocateVex(G, v2); if (!(pi = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 pi->adjvex = j; pi->info = 0; //插入連結串列G.vertices[i] pi->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = pi; }//for return OK; }//CreateDG //有向網 Status CreateDN(ALGraph &G) { int i, j, k, IncInfo; ArcNode *pi, *pj; char v1, v2; cout << "輸入頂點數G.vexnum:"; cin >> G.vexnum; cout << "輸入邊數G.arcnum:"; cin >> G.arcnum; cout << "輸入是否有Info資訊(0、沒有,1、有)"; cin >> IncInfo; getchar(); for (i = 0; i < G.vexnum; ++i) { cout << "輸入頂點G.vertices[" << i << "].data:"; cin >> G.vertices[i].data; getchar(); //初始化連結串列頭指標為空 G.vertices[i].firstarc = NULL; } /* 輸入各邊並構造鄰接表 */ for (k = 0; k < G.arcnum; ++k) { cout << "請輸入第" << k + 1 << "條邊的兩個頂點和相連邊的權值:" << endl; //輸入一條邊的起點和終點 cin >> v1; cin >> v2; cin >> IncInfo; getchar(); //確定V1和V2在G中的位置 i = LocateVex(G, v1); j = LocateVex(G, v2); if (!(pi = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 pi->adjvex = j; //插入連結串列G.vertices[i] pi->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = pi; pi->info = IncInfo; }//for return OK; }//CreateDN //無向網 Status CreateUDN(ALGraph &G) { int i, j, k, IncInfo; ArcNode *pi, *pj; char v1, v2; cout << "輸入頂點數G.vexnum:"; cin >> G.vexnum; cout << "輸入邊數G.arcnum:"; cin >> G.arcnum; cout << "輸入是否有Info資訊(0、沒有,1、有)"; cin >> IncInfo; getchar(); for (i = 0; i < G.vexnum; ++i) { cout << "輸入頂點G.vertices[" << i << "].data:"; cin >> G.vertices[i].data; getchar(); //初始化連結串列頭指標為空 G.vertices[i].firstarc = NULL; } /* 輸入各邊並構造鄰接表 */ for (k = 0; k < G.arcnum; ++k) { cout << "請輸入第" << k + 1 << "條邊的兩個頂點和相連邊的權值:" << endl; //輸入一條邊的起點和終點 cin >> v1; cin >> v2; cin >> IncInfo; getchar(); //確定V1和V2在G中的位置 i = LocateVex(G, v1); j = LocateVex(G, v2); if (!(pi = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 pi->adjvex = j; //插入連結串列G.vertices[i] pi->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = pi; pi->info = IncInfo; if (!(pj = (ArcNode *)malloc(sizeof(ArcNode)))) exit(OVERFLOW); //對弧結點賦鄰接點"位置"資訊 pj->adjvex = i; //插入連結串列G.vertices[i] pj->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = pi; pj->info = IncInfo; }//for return OK; }//CreateUDN Status CreateGraph(ALGraph &G) { cout << "請輸入圖的種類:0表示DG,1表示DN,2表示UDG,3表示UDN" << endl; cin >> G.kind; switch (G.kind) { case 0: return CreateDG(G); case 1: return CreateDN(G); case 2: return CreateUDG(G); case 3: return CreateUDN(G); default: return ERROR; } } void list(ALGraph G) { int i; ArcNode *p; cout << "輸出鄰接表((0)代表無權值):" << endl; for (i = 0; i < G.vexnum; ++i) { cout << i << ":" << G.vertices[i].data; p = G.vertices[i].firstarc; while (p) { cout << setw(3) << p->adjvex; cout << "(" <<p->info<< ")"; p = p->nextarc; } cout << endl; } } void DFS(ALGraph G, int v) { ArcNode *p; int w; visited[v] = TRUE; cout << G.vertices[v].data << " "; for (p = G.vertices[v].firstarc; p; p = p->nextarc) { w = p->adjvex; if (!visited[w])//對v的尚未訪問的鄰接頂點w遞迴呼叫DFS DFS(G, w); } } //深度優先遍歷 void DFSTraverse(ALGraph G) { int v; for (v = 0; v < G.vexnum; ++v) { visited[v] = FALSE; } for (v = 0; v < G.vexnum; ++v) { if (!visited[v]) { DFS(G, v); cout << endl; } } } void BFSTraverse(ALGraph G) { int v,w; //輔助佇列 int front=0, rear = 0; VNode Queue[MAX_VERTEX_NUM]; ArcNode *p; //初始化標誌陣列 for (v = 0; v < G.vexnum; ++v) { visited[v] = FALSE; } for (v = 0; v < G.vexnum; ++v) { if (!visited[v])//v尚未訪問 { visited[v] =true; cout << G.vertices[v].data<<" "; Queue[++rear] = G.vertices[v];//v入佇列 while (front != rear)//判斷佇列是否為空 { VNode u = Queue[++front];//隊頭元素出佇列,並等於u cout << endl; /* 判斷該結點的後序表結點,存在即輸出,入佇列 */ for (p = u.firstarc; p; p = p->nextarc) { w = p->adjvex; if (!visited[w]) { visited[w] = true; cout << G.vertices[w].data << " "; Queue[++rear] = G.vertices[w]; }//if }//for }//while }//if }//for }//BFSTraverse void main() { ALGraph G; CreateGraph(G); list(G); //深度優先遍歷圖 cout << "深度優先遍歷:"; DFSTraverse(G); cout << endl; //廣度優先遍歷 cout << "廣度優先遍歷:"; BFSTraverse(G); system("pause"); }