資料結構複習——圖的廣度優先搜尋
阿新 • • 發佈:2019-01-22
1、和樹的遍歷類似,我們希望從圖中某一定點出發訪遍圖中的其餘節點,且每個節點僅被訪問一次。
2、實現。
//假定圖最多有20個定點 #define MAX_VERTEX_NUM 20 bool visited[MAX_VERTEX_NUM]={false}; //採用鄰接連結串列的方式來儲存圖中的節點 struct Node { unsigned NodeID_; Node* next_; Node(unsigned nodeId): NodeID_(nodeId), next_(nullptr) { } Node() { } }; struct Graph { //頭節點組成的陣列 Node nodeList[MAX_VERTEX_NUM]; //定點個數、弧的個數 int verNum_,arcNum_; Graph() { } }; //建立採用鄰接表儲存的圖 void createAGraph(Graph& graph) { //假定有5個頂點,6條邊 graph.verNum_=5; graph.arcNum_=7; for(int i=0;i<graph.verNum_;++i) { graph.nodeList[i].NodeID_=i; graph.nodeList[i].next_=nullptr; } Node* p2=nullptr; for(unsigned i=0;i<5;++i) { for(unsigned j=0;j<5;++j) { if(i*j!=4&&i*j!=8&&i*j!=12&& i!=j) { p2=new Node(j); std::cout<<i<<"\t"<<j<<"\t"; p2->next_=graph.nodeList[i].next_; graph.nodeList[i].next_=p2; } } std::cout<<std::endl; } } void printGraph(Graph& graph) { std::cout<<"輸出頂點資訊:\n"; Node* curNode=nullptr; for(int i=0;i<graph.verNum_;++i) { std::cout<<"頂點編號"<<graph.nodeList[i].NodeID_<<std::endl; curNode=graph.nodeList[i].next_; while(curNode) { std::cout<<":--->"<<curNode->NodeID_; curNode=curNode->next_; } std::cout<<std::endl; } } /** * @brief firstAdjvex 在圖graph中返回頂點編號為adjvexNo對應的鄰接表中的首個節點編號 * @param graph * @param adjvexNo * @return */ int firstAdjvex(Graph& graph,int adjvexNo) { int firstNodeID=graph.nodeList[adjvexNo].next_->NodeID_; return firstNodeID; } /** * @brief nextAdjvex 在圖graph的編號nodeListNo對應的鄰接連結串列中返回 * 編號為adjvexNo的結點的下一個結點編號 * @param graph * @param nodeListNo * @param adjvexNo * @return */ int nextAdjvex(Graph& graph,unsigned nodeListNo,unsigned adjvexNo) { Node* curNode=graph.nodeList[nodeListNo].next_; while(curNode) { if(curNode->NodeID_==adjvexNo&&curNode->next_!=nullptr) { return curNode->next_->NodeID_; } curNode=curNode->next_; } return -1; } std::queue<int> listNodeQue; void BFSTraverse(Graph& graph) { int i=-1; for(i=0;i<graph.verNum_;++i) visited[i]=false; for(i=0;i<graph.verNum_;++i) { if(visited[i]==false) { visited[i]=true; std::cout<<i<<"--->\t"; listNodeQue.push(i); while(!listNodeQue.empty()) { int j=listNodeQue.front(); listNodeQue.pop(); for(int k=firstAdjvex(graph,j);k>=0;k=nextAdjvex(graph,j,k)) { if(visited[k]==false) { visited[k]=true; std::cout<<k<<"--->\t"; listNodeQue.push(k); } } } } } } //測試函式 int main() { Graph graph; createAGraph(graph); printGraph(graph); // DFSTraverse(graph); BFSTraverse(graph); return 0; }
3、執行結果。