用鄰接多重表表示一個無向圖,並給出DFS和BFS搜索代碼。鄰接多重表好處就是賊直觀,幾條邊就幾個邊表的元素。
代碼如下:
邊表節點定義(其實就是邊的定義)
typedef struct EdgeNode //鄰接多重表 { int iVertex; EdgeNode* iLink; int jVertex; EdgeNode* jLink; };
頂點表節點的定義
template <typename Type> struct VextexNode //鄰接多重表的頂點表 { Type Data; EdgeNode* TailLink; Mark Flag; };
最後是圖的模板類
#ifndef MULADJACENCYLIST_H #define MULADJACENCYLIST_H #include "SideNode.h" #include "VexNode.h" #include <iostream> #include <vector> #include <list> #include <set> using namespace std; template <typename Type, int N> class MulAdjacencyList { public: MulAdjacencyList(); ~MulAdjacencyList(); void AddEdge(); int DeleteEdge(int x, int y); void DFS(int x, const Type& Value); void BFS(int x, const Type& Value); private: int InitEdgeNum(); //構造函數中先輸入圖的邊數 int NextIndex(int CurIndex); //查找最近的一個鄰接點,CurIndex爲點的下標而不是值 void BFSHelper(set <int> SourceList, const Type& Value); //BFS真正的遞歸函數 void AllNextIndex(int i); //和i相連的所有鄰接點,i爲點的下標而不是值 VextexNode <Type> VertexArray[N]; //頂點表 EdgeNode* LastPtr(int x); int EdgeNums; //當前的邊數 vector <int> Temp; //用來存放搜索結果的容器 set <int> TempList; //用來存放AllNextIndex結果的容器 }; template <typename Type, int N> void MulAdjacencyList<Type, N>::AddEdge() //添加一條x到y的無向邊 { cout << "Enter the edge wanna insert!" << endl; int i, j; if (cin >> i >> j) { EdgeNode* TarPtr = new EdgeNode; TarPtr->iVertex = i; TarPtr->jVertex = j; TarPtr->iLink = VertexArray[i].TailLink; TarPtr->jLink = VertexArray[j].TailLink; VertexArray[i].TailLink = TarPtr; VertexArray[j].TailLink = TarPtr; EdgeNums++; } else cin.clear(); } template <typename Type, int N> int MulAdjacencyList<Type, N>::InitEdgeNum() { cout << "Enter the quantity of edges!"<< endl; cin >> EdgeNums; return EdgeNums; } template <typename Type, int N> EdgeNode* MulAdjacencyList<Type, N>::LastPtr(int x) //找到和x相關的最後一條邊 { EdgeNode* Temp = VertexArray[x].TailLink; EdgeNode* LastTemp = Temp; while (Temp != NULL) { if (Temp->iVertex == x) { LastTemp = Temp; Temp = Temp->iLink; } else if (Temp->jVertex == x) { LastTemp = Temp; Temp = Temp->jLink; } } return LastTemp; } template <typename Type, int N> MulAdjacencyList <Type, N>::MulAdjacencyList() { cout << "enter the vertex for the graph!" << endl; for (int i = 0; i != N; ++i) { cin >> VertexArray[i].Data; VertexArray[i].TailLink = NULL; VertexArray[i].Flag = No; } int Temp = InitEdgeNum(); for (int i = 0; i != Temp; ++ i) AddEdge(); } template <typename Type, int N> int MulAdjacencyList<Type, N>::DeleteEdge(int x, int y) //刪除x到y的一條無向邊 { if (x == y)return 0; EdgeNode* Q = VertexArray[x].TailLink; //Q的下一條邊就是要刪除的邊 EdgeNode* P = VertexArray[x].TailLink; //先從x出發找到要刪除的邊,調整完x的邊的次序,得到指針,最後再刪除 if (P && P->jVertex == y) //假如第一條邊就是待刪除的邊, P是前向判斷,避免P爲NULL的情況下還執行P->jVertex VertexArray[x].TailLink = P->iLink; else if (P && P->iVertex == y) VertexArray[x].TailLink = P->jLink; else //假如第一條邊不是要刪除的邊,則向下查找 { while (P) { if (P->iVertex == x && P->jVertex != y)//不是要刪除的邊 { Q = P; P = P->iLink; } else if (P->jVertex == x && P->iVertex != y) { Q = P; P = P->jLink; } else //找到了鄰接點y break; } if (P == NULL) { return 0; //這裏可以加入一句警告“Not Found” } else if (P->iVertex == x && P->jVertex == y) //找到了邊(x,y),調整x的邊的次序 { if (Q->iVertex == x) Q->iLink = P->iLink; else Q->jLink = P->iLink; } else if (P->iVertex == y && P->jVertex == x) { if (Q->iVertex == x) Q->iLink = P->jLink; else Q->jLink = P->jLink; } } P = VertexArray[y].TailLink; //從y出發開始查找,調整y的邊的次序 if (P && P->iVertex == x) VertexArray[y].TailLink = P->jLink; else if (P && P->jVertex == x) VertexArray[y].TailLink = P->iLink; else { while (P != NULL) { if (P->iVertex == y && P->jVertex != x) { Q = P; P = P->iLink; } else if (P->jVertex == y && P->iVertex != x) { Q = P; P = P->jLink; } else break; } if (P == NULL) //由於上面打了一次警告,這裏就不打警告了 return 0; else if (P->iVertex == y && P->jVertex == x) { if (Q->iVertex == y) Q->iLink = P->iLink; else Q->jLink = P->iLink; } else if ((P->jVertex == y && P->iVertex == x)) { if (Q->iVertex == y) Q->iLink = P->jLink; else Q->jLink = P->jLink; } } cout << x << endl << y << endl<<"yici"<<endl; if (P != NULL) delete P; //調整完線序了,刪掉邊 --EdgeNums; return 1; } template <typename Type, int N> MulAdjacencyList <Type, N>::~MulAdjacencyList() { for (int i = 0; i != N; ++i) { for (int j = 0; j != N; ++j) DeleteEdge(i,j); } } template <typename Type, int N> void MulAdjacencyList <Type, N>::AllNextIndex(int i) //找到和i相關聯的所有的點 { EdgeNode* Ptr = VertexArray[i].TailLink; while (Ptr != NULL) { if (Ptr->iVertex == i) { if (VertexArray[Ptr->jVertex].Flag != Yes)TempList.insert(Ptr->jVertex); Ptr = Ptr->iLink; } else { if (VertexArray[Ptr->iVertex].Flag != Yes)TempList.insert(Ptr->iVertex); Ptr = Ptr->jLink; } } } template <typename Type, int N> int MulAdjacencyList <Type, N>::NextIndex(int CurIndex) { EdgeNode* Ptr = VertexArray[CurIndex].TailLink; while (Ptr != NULL) { if (Ptr->iVertex == CurIndex) { if (VertexArray[Ptr->jVertex].Flag == No){ return Ptr->jVertex; } else Ptr = Ptr->iLink; } else if (Ptr ->jVertex == CurIndex) { if (VertexArray[Ptr->iVertex].Flag == No){ return Ptr->iVertex; } else Ptr = Ptr->jLink; } } if (Ptr == NULL) { return N; } } template <typename Type, int N> void MulAdjacencyList <Type, N>::DFS(int x, const Type& Value) //x爲起始的下標,Value爲查找的值 { if (VertexArray[x].Data == Value) { Temp.push_back(x); } VertexArray[x].Flag = Yes; int TempIndex = NextIndex(x); while (TempIndex != N) { DFS(TempIndex, Value); TempIndex = NextIndex(x); } for (vector <int>::const_iterator i = A.Temp.begin(); i != A.Temp.end(); ++i) //打印找到的元素 cout << *i << endl; } template <typename Type, int N> void MulAdjacencyList <Type, N>::BFSHelper(set <int> SourceList,const Type& Value) { if (!SourceList.empty()) { for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i) { VertexArray[*i].Flag = Yes; if (VertexArray[*i].Data == Value) Temp.push_back(*i); } for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i) { AllNextIndex(*i); } SourceList = TempList; TempList.clear(); BFSHelper(SourceList, Value); } } template <typename Type, int N> void MulAdjacencyList <Type, N>::BFS(int x, const Type& Value) { set <int> Set; Set.insert(x); BFSHelper(Set, Value); } #endif
大類的代碼有點亂,先挖個坑以後有空再來填上,希望對各位和自己有幫助。