圖的儲存(鄰接表)建立與深度優先、廣度優先搜尋
阿新 • • 發佈:2019-01-29
#pragma once #include<iostream> #include<queue> using namespace std; #define Vnum 10 typedef int DATA; /*鄰接表儲存圖*/ typedef struct list //儲存連結串列的結構 { int weight; //邊 int index; //頂點陣列的索引 struct list *nextList; //連結串列的下一個節點 }LIST; typedef struct vex { DATA data; //頂點需要儲存的資料 LIST * firstList; //指向連結串列的第一個節點 } VEX; class CGraph { private: bool visited[Vnum]; //標記索引為Vnum的頂點是否被訪問 VEX vex[Vnum]; //以鄰接表的形式儲存整個圖的資訊 public: CGraph() //圖物件在建立的時候的自動初始化 { for(int i =0; i < Vnum; i++) { vex[i] = {}; visited[i] = false; } } void CreateGraph() //圖的建立,即鄰接表的建立 { for(int i = 0; i < Vnum; i++) { int v = 0, weight = 0; vex[i].firstList = new LIST; LIST *temp = vex[i].firstList; cout << "輸入與第" << i << "個頂點相連的頂點與對應邊" << endl; cin >> v >> weight; temp->index = v; temp->weight = weight; while( v != -1) { cout << "再次輸入與第" << i << "個頂點相連的頂點與對應邊" << endl; cin >> v >> weight; if(v != -1) { temp->nextList = new LIST; temp = temp->nextList; temp->index = v; temp->weight = weight; } else { temp->nextList = NULL; } } } int a = 0; } void DFS( int v) //深度優先搜尋 { LIST *p = vex[v].firstList; cout << v << endl; visited[v] = true; while (p) //列出所有狀態轉換的可能性 { if (!visited[p->index]) //如果此狀態可轉換 { DFS(p->index); //遞迴進下一層深度 } p = p->nextList; //轉換到下一狀態 } } void BFS(int v) //廣度優先搜尋 { cout << v << endl; LIST *p = vex[v].firstList; queue<LIST*> q; q.push(p); //先把初始頂點對應的連結串列第一節點放進佇列,使其不空佇列 LIST *temp = p; while(!q.empty()) //每進行一次大迴圈,會把當前頂點對應的所有未訪問過連結串列節點指標放入佇列 { while(temp->nextList) { if (!visited[temp->nextList->index]) { q.push(temp->nextList); visited[temp->nextList->index] = true; } temp = temp->nextList; } cout << q.front()->index << endl; //然後輸出(一個)最先放進去的也就是最前面的資料資訊。 temp = vex[q.front()->index].firstList; //此頂點所連線的所有點已經訪問完畢,開始訪問其他排隊在前面的沒訪問過的節點 q.pop(); //訪問到它了,可以出隊了 } } ~CGraph() //物件銷燬時順便清理連結串列空間 { for(int i = 0; i < Vnum; i++) { LIST *p = vex[i].firstList; LIST *temp = NULL; while(p) { temp = p->nextList; delete p; p = temp; } } } };