用鄰接表儲存有向圖實現的dfs和bfs
阿新 • • 發佈:2019-01-31
dfs就是先訪問某個頂點,然後將與之相連的並且是未被訪問過的頂點進行遞迴呼叫(找尋該頂點需要一層迴圈) 同時為了防止出現不連通的情況,將呼叫DFS()時傳入的頂點進行一層迴圈(1~頂點數)遍歷 BFS用棧來實現,#include<iostream> #include<stdlib.h> #define MAX 20 using namespace std; class ArcNode { public: int adjvex; //儲存弧的終止位置 ArcNode*nextarc; }; class VNode { public: char data; //結點資訊 ArcNode*firsarc;//第一個弧邊的地址 }; //定義圖的相關資訊 class Graph { public: VNode Node[MAX]; int arcnum;//弧邊的個數 int vexnum;//定點的個數 }; //主函式相關內容 void dfs(Graph G, int v); void bfs(Graph G); int visited[MAX];//標記dfs的陣列,看有沒有被訪問過 int book[MAX]; //標記bfs的陣列,看有沒有被訪問過 int main() { //儲存圖的相關資訊 Graph G; int i; for (i = 1; i <= MAX; i++) { G.Node[i].firsarc = NULL; } cout << "輸入圖的結點個數和弧的個數\n"; cin >> G.vexnum; cin >> G.arcnum; cout << "輸入各結點按順序編號下對應資訊:"; for (i = 1; i <= G.vexnum; i++) { cin >> G.Node[i].data; } cout << "輸入弧的資訊\n"; char start, end; //儲存弧的起始點,終止點 int s, t;//儲存起始點,終止點的編號 int j; ArcNode*ptr, *p; for (i = 1; i <= G.arcnum; i++) { cin >> start; cin >> end; getchar(); for (j=1;j <= G.vexnum; j++) { if (start == G.Node[j].data) s = j; if (end == G.Node[j].data) t =j; } ptr=new ArcNode; ptr->adjvex = t; if (G.Node[s].firsarc == NULL) { G.Node[s].firsarc = ptr; } else { p = G.Node[s].firsarc; while (p->nextarc) //注意這裡只能是p->nextarc,要不然,p=NULL再退出就沒有意義了 { p = p->nextarc; } p->nextarc = ptr; } cout << "sss\n"; ptr->nextarc = NULL; } /*//輸出檢查 for (i = 1; i <= G.vexnum; i++) { cout << G.Node[i].data << endl; p=G.Node[i].firsarc; while (p) { cout << "ppp\n"; cout << p->adjvex << endl; p = p->nextarc; } }*/ for(i=1;i<=G.vexnum;i++) //防止圖是不連通的圖 { if(visited[i]!=1) dfs(G,i); } cout << "\n"; bfs(G); system ("pause"); return 0; } void dfs(Graph G, int v) { cout << G.Node[v].data; visited[v] = 1; ArcNode*p = G.Node[v].firsarc; while (p) { if (visited[p->adjvex] == 0) dfs(G, p->adjvex); else p = p->nextarc; } } void bfs(Graph G) { //定義佇列,並且對佇列進行初始化 char queue[MAX] = { '\0' }; int front = 0, rear = 1, i, j; ArcNode*ptr; for (j = 1; j <= G.vexnum; j++) //這是為了防止圖不是聯通的 { if (book[j] != 1) { cout << G.Node[j].data; //在其進佇列之前對其進行訪問輸出 book[j] = 1; queue[rear++] = G.Node[j].data; //從定點開始,不斷進行出隊,輸出,將定點有關的終點入隊,直到佇列為空 while (rear -1 != front) { for (i = 1; queue[front+1] != G.Node[i].data; i++); front++; ptr = G.Node[i].firsarc; while (ptr) { if (book[ptr->adjvex] != 1) { cout << G.Node[ptr->adjvex].data; book[ptr->adjvex] = 1; queue[rear++] = G.Node[ptr->adjvex].data; } ptr = ptr->nextarc; } } } } }