1. 程式人生 > >鄰接表表示圖(有向、無向圖)及廣度、深度遍歷)

鄰接表表示圖(有向、無向圖)及廣度、深度遍歷)

鄰接表表示圖

#include <iostream>
#include <malloc.h>
#include <queue>
using namespace std;

#define VertexType char
#define MaxVertexNum 20         //最大頂點數

queue<int>Q;                    //輔助佇列

enum GraphType{DG, UDG};        //DG表示有向圖,UDG表示無向圖

typedef struct ArcNode{         //邊結點
int adjvex; //鄰接點的下標 struct ArcNode *nextarc; //後繼鏈指標 }ArcNode; typedef struct VNode{ //頂點結點 VertexType data; //頂點資料 ArcNode *firstarc; //邊鏈頭指標 }VNode, AdjList[MaxVertexNum]; typedef struct{ AdjList vertices; //鄰接表 int vexnum,
arcnum; //頂點數和邊數 GraphType kind; //圖種類標誌 }ALGraph; //建立有向圖 void CreateDGGraph(ALGraph &G) { int m, n; //邊<Vm,Vn>的下標 ArcNode *vm, *vn; //構成邊<Vm,Vn>的兩個頂點 cout << "請輸入頂點數和邊數:"; cin >> G.vexnum >> G.arcnum; cout <<
"請輸入頂點的資訊:" << endl; //獲取頂點資訊 for(int i=0; i<G.vexnum; i++) { cin >> G.vertices[i].data; G.vertices[i].firstarc=NULL; } //建立鄰接表,採用頭插法 for(int i=0; i<G.arcnum; i++) { cout << "請輸入<Vi,Vj>的下標:"; cin >> m >> n; vm=(ArcNode*)malloc(sizeof(ArcNode)); vm->adjvex=n; vm->nextarc=NULL; if(G.vertices[m].firstarc==NULL) { vn=G.vertices[m].firstarc=vm; } else { vn=vn->nextarc=vm; } } } //建立無向圖 void CreateUDGGraph(ALGraph &G) { int m, n; //邊<Vm,Vn>的下標 ArcNode *pe; cout << "請輸入頂點數和邊數:"; cin >> G.vexnum >> G.arcnum; cout << "請輸入頂點的資訊:" << endl; //獲取頂點資訊 for(int i=0; i<G.vexnum; i++) { cin >> G.vertices[i].data; G.vertices[i].firstarc=NULL; } //建立鄰接表,採用頭插法 for(int i=0; i<G.arcnum; i++) { cout << "請輸入<Vi,Vj>的下標:"; cin >> m >> n; pe=(ArcNode*)malloc(sizeof(ArcNode)); pe->adjvex=n; pe->nextarc=G.vertices[m].firstarc; G.vertices[m].firstarc=pe; pe=(ArcNode*)malloc(sizeof(ArcNode)); pe->adjvex=m; pe->nextarc=G.vertices[n].firstarc; G.vertices[n].firstarc=pe; } } void PrintALGraph(ALGraph &G) { ArcNode *p; for (int i=0;i<G.vexnum;i++) { cout << "頂點" << i << "(" << G.vertices[i].data << ") "": "; for (p=G.vertices[i].firstarc; p!=NULL;p=p->nextarc) cout << p->adjvex << "(" << G.vertices[p->adjvex].data << ") "; if (p==NULL) cout << endl; } } //求圖中頂點v的第一個鄰接點,若有則返回頂點下標。若v沒有鄰接點或圖中不存在v,則返回-1 int FirstNeighbor(ALGraph G, int v) { ArcNode *next=G.vertices[v].firstarc; if(next) { return next->adjvex; } return -1; } //返回除頂點v外的下一個頂點w int NextNeighbor(ALGraph G, int v, int w) { ArcNode *next=G.vertices[v].firstarc; while(next) { if(next->adjvex==w)break; next=next->nextarc; } if(next) { ArcNode *nextNode=next->nextarc; if(nextNode) { return nextNode->adjvex; } } return -1; } void visit(ALGraph G, int v) { cout << G.vertices[v].data << " "; } bool visited[MaxVertexNum]; //訪問標記陣列 //從頂點v出發,採用遞迴,廣度遍歷圖G void BFS(ALGraph G, int v) { visit(G, v); visited[v]=true; //設已訪問標記 Q.push(v); //頂點v入隊 while(!Q.empty()) { v=Q.front(); Q.pop(); for(int w=FirstNeighbor(G, v); w>=0; w=NextNeighbor(G, v, w)) { //檢查v所以鄰接點 if(!visited[w]) //w為v的尚未訪問的鄰接頂點 { visit(G, w); visited[w]=true; //設已訪問標記 Q.push(w); //頂點w入隊 } } } } //從頂點出發,進行廣度優先遍歷 void BFSTraverse(ALGraph G) { for(int i=0; i<G.vexnum; i++) { visited[i]=false; //訪問標記陣列初始化 } for(int i=0; i<G.vexnum; i++) //從0號頂點開始遍歷 { if(!visited[i]) { BFS(G, i); //vi未訪問過,從vi開始BFS } } } //從頂點v出發,採用遞迴,深度遍歷圖G void DFS(ALGraph G, int v) { visit(G, v); //訪問v visited[v]=true; //設已訪問標記 for(int w=FirstNeighbor(G, v); w>=0; w=NextNeighbor(G, v, w)) { //w為v的尚未訪問的鄰接頂點 if(!visited[w]) { DFS(G, w); } } } //從頂點出發,進行深度優先遍歷 void DFSTraverse(ALGraph G) { for(int i=0; i<G.vexnum; i++) { visited[i]=false; //訪問標記陣列初始化 } for(int i=0; i<G.vexnum; i++) //從0號頂點開始遍歷 { if(!visited[i]) { DFS(G, i); //vi未訪問過,從vi開始DFS } } } int main() { ALGraph G; //CreateALGraph(G); int tag; //有向無向圖標誌 cout << "請輸入1(有向圖),2(無向圖):"; cin >> tag; if(tag==1) { G.kind=DG; CreateDGGraph(G); //建立有向圖 } else { G.kind=UDG; CreateUDGGraph(G); //建立無向圖 } cout << "===========================" << endl; PrintALGraph(G); cout <<endl; cout << "廣度遍歷:"; BFSTraverse(G); cout << endl; cout << "深度遍歷:"; DFSTraverse(G); return 0; }

有向圖測試

有向圖的建立和廣度、深度遍歷

無向圖測試

無向圖的建立和廣度、深度遍歷