c++ 圖(鄰接表)
阿新 • • 發佈:2019-02-02
/*
連通鄰接表:
由頂點表和邊表組成,頂點表中存著資料和指向邊表的指標
邊表是一個鏈,存著頂點表的相關聯的資料在頂點表的位置與權值
下面就是建表 遍歷(深度優先DFS與廣度優先BFS)
*/
#include <iostream> #define MAXSIZE 30 using namespace std; typedef struct Sidetable //邊表節點結構體 { int DataPosition; int Weight; Sidetable* Next; }Side_Table; typedef struct Vertextable //頂點表結構體 { char Data; Sidetable* Size_Headptr; }Vertex_Table; class Map //圖類 { private: int Visited[MAXSIZE]; int Nums; //實際資料個數 Vertex_Table DataArry[MAXSIZE]; //物件陣列 public: Map() //初始化建構函式 { Nums = 0; for(int i = 0; i <= MAXSIZE; i++) { DataArry[i].Data = '\0'; //初始化頂點表資料域 DataArry[i].Size_Headptr = NULL; //初始化頂點表指標域 Visited[i] = 0; } } ~Map() //解構函式,在沒寫解構函式的時候 { //程式雖然執行完了 但是終止了,記憶體錯誤,寫上解構函式就沒事了 //看來解構函式還是必要的 Side_Table* p; for(int i = 1; i <= Nums; i++) { p = DataArry[i].Size_Headptr; while(p) { DataArry[i].Size_Headptr = p->Next; delete p; p = DataArry[i].Size_Headptr; } } } void SetData(); //輸入資料 int Re_Nums(){return Nums;} void VisitedClear(); void Set_Endgsrelationship(); //設定頂點關係及建圖 int Re_Position(char); //返回資料在物件陣列中的位置 //***********遍歷函式 void DFSljb(int); //深度優先搜尋 void TheDFSljb(); void BFSljb(); //廣度優先搜尋 }; void Map::VisitedClear() { for(int i = 0; i < MAXSIZE; i++) { Visited[i] = 0; } } void Map::SetData() { int i = 1; while(cin>>DataArry[i].Data,DataArry[i].Data != '.') { i++; Nums++; } } int Map::Re_Position(char ch) { int i = 1; while(i <= Nums) { if(DataArry[i].Data == ch) { break; } i++; } return i; } void Map::DFSljb(int i) { Side_Table* p; cout<<DataArry[i].Data<<" "; Visited[i] = 1; p = DataArry[i].Size_Headptr; while(p != NULL) { if(Visited[p->DataPosition] == 0) { DFSljb(p->DataPosition); } p = p->Next; } } void Map::TheDFSljb() { DFSljb(1); // 從第一個開始遍歷 } void Map::Set_Endgsrelationship() { int pos1,pos2,weight; //pos為輸入資料在物件陣列中的位置 char ch1,ch2; Side_Table* p; while(cin>>ch1>>ch2>>weight,ch1 != '.' && ch2 != '.') { pos1 = Re_Position(ch1); //儲存字元位置 pos2 = Re_Position(ch2); p = new Side_Table(); p->DataPosition = pos2; p->Weight = weight; p->Next = DataArry[pos1].Size_Headptr; DataArry[pos1].Size_Headptr = p; p = new Side_Table(); //因為建立的是無向圖,所以還要加成pos2-》pos1 p->DataPosition = pos1; //若要改成有向只要吧這四行去掉就行了 p->Weight = weight; p->Next = DataArry[pos2].Size_Headptr; DataArry[pos2].Size_Headptr= p; } } void Map::BFSljb() { VisitedClear(); int i,queue[MAXSIZE],front = 0,rear = 0; Side_Table* p; cout<<DataArry[1].Data<<" "; //從1開始遍歷 Visited[1] = 1; rear = rear + 1; queue[rear] = 1; //入隊 while(front != rear) { front = front + 1; i = queue[front]; //出隊 p = DataArry[i].Size_Headptr; while(p != NULL) { if(Visited[p->DataPosition] == 0) // 如果為訪問 { cout<<DataArry[p->DataPosition].Data<<" "; //列印 Visited[p->DataPosition] = 1; //標記 rear = rear + 1; queue[rear] = p->DataPosition; //入隊 //p指向另一相關聯頂點 } p = p->Next; } } } int main() { Map map1; cout<<"請輸入頂點資料(以'.'結束輸入):"; map1.SetData(); cout<<endl<<"您一共輸入了"<<map1.Re_Nums()<<"個數據."<<endl<<endl; cout<<"請輸入頂點關係及權值(以. . 結束輸入):"<<endl; map1.Set_Endgsrelationship(); cout<<"深度優先搜尋遍歷圖為:"; map1.TheDFSljb();cout<<endl; cout<<"廣度優先搜尋遍歷圖為:"; map1.BFSljb();cout<<endl; return 0; } /* a b 1 a c 2 c d 3 */v