zoukankan      html  css  js  c++  java
  • 无向图的深度优先与广度优先搜索代码实现

    图采用了邻接表的形式储存。

    带不带权都无所谓的

    深度优先搜索 Depth First Search

    道理和树的先序遍历差不多,把将要访问的点入栈,然后从栈里取点进行访问。

    有些被调用的函数的具体代码将会在文章最后补上 ,但是函数功能看注释就好了

     1 void GraphAdjacencyListWeight::DFSAdvanced(int StartVertex) {
     2     int *visited = new int[VertexNumber];
     3     memset(visited, 0, VertexNumber * sizeof(int));
     4 
     5     stack<int> S;
     6     S.push(StartVertex);
     7 
     8     int NextVertex = -1;
     9 
    10     while (!IsAllVisited(visited)) {
    11         //如果有其他的连通分量
    12         if (S.empty()) {
    13             //随便找一个没被访问的点丢进栈
    14             for (int lop = 0; lop < VertexNumber; lop++) {
    15                 if (visited[lop] == 0) {
    16                     S.push(lop);
    17                     break;
    18                 }
    19             }
    20         }
    21         while (!S.empty()) {
    22             NextVertex = S.top();
    23             S.pop();
    24 
    25             if (visited[NextVertex] != 1) {
    26                 //访问该点
    27                 VisitVertex(NextVertex);
    28                 //标记为访问过
    29                 visited[NextVertex] = 1;
    30                 //将下一个没被访问过的邻接点入栈
    31                 PushValidVertexToStack(S, NextVertex, visited);
    32             }
    33         }
    34     }
    35     delete []visited;
    36 }
    DFS

    令人惊讶的是广度优先搜索与深度优先搜索的代码居然是几乎相同的,除了栈换成队列。。。惊呆

    广度优先搜索 Breadth First Search

    广度优先搜索的过程和树的层序遍历类似 

     1 //广度优先
     2 void GraphAdjacencyListWeight::BFSAdvanced(int StartVertex) {
     3     int *visited = new int[VertexNumber];
     4     memset(visited, 0, VertexNumber * sizeof(int));
     5 
     6     queue<int> Q;
     7     Q.push(StartVertex);
     8 
     9     //下一个将要访问的顶点的序号
    10     int NextVertex = -1;
    11 
    12     //当还有顶点没被访问时
    13     while (!IsAllVisited(visited)) {
    14         //如果有其他的连通分量
    15         if (Q.empty()) {
    16             //随便找一个没被访问的点丢进队列
    17             for (int lop = 0; lop < VertexNumber; lop++) {
    18                 if (visited[lop] == 0) {
    19                     Q.push(lop);
    20                     break;
    21                 }
    22             }
    23         }
    24 
    25         while (!Q.empty()) {
    26             //获取队列前端元素
    27             NextVertex = Q.front();
    28             Q.pop();
    29 
    30             //如果该点没被访问过
    31             if (visited[NextVertex] != 1) {
    32                 //访问该点
    33                 VisitVertex(NextVertex);
    34                 //标记为访问过
    35                 visited[NextVertex] = 1;
    36                 //将该点的邻接点入队
    37                 EnQueueAllAdjVer(Q, NextVertex);
    38             }
    39         }
    40     }
    41     delete []visited;
    42 }
    BFS

    下面贴上完整的用到的函数的代码

     1 int GraphAdjacencyListWeight::IsAllVisited(int visit[]) {
     2     for (int lop = 0; lop < VertexNumber; lop++) {
     3         if (visit[lop] == 0) {
     4             return 0;
     5         }
     6     }
     7     return 1;
     8 }
     9 
    10 void GraphAdjacencyListWeight::VisitVertex(int i) {
    11     cout << "Vertex : " << VectorVertexList[i]->VertexIndex << endl;
    12 }
    13 
    14 void GraphAdjacencyListWeight::EnQueueAllAdjVer(queue<int> &Q, int index) {
    15     for (auto tmpPtr = VectorVertexList[index]->firstArc; tmpPtr != nullptr; tmpPtr = tmpPtr->nextArc) {
    16         Q.push(tmpPtr->AdjacencyNode);
    17     }
    18 }
    19 
    20 void GraphAdjacencyListWeight::PushValidVertexToStack(stack<int> &S, int index, int visit[]) {
    21     for (auto Ptr = VectorVertexList[index]->firstArc; Ptr != nullptr; Ptr = Ptr->nextArc) {
    22         if (visit[Ptr->AdjacencyNode] != 1) {
    23             S.push(Ptr->AdjacencyNode);
    24             return;
    25         }
    26     }
    27 }
    Functions

     最后一行的 return; 不要

     全部代码请看 GitHub

  • 相关阅读:
    黄聪:解决Bootstrap模态框(modal)弹出后页面跑到顶部的办法
    黄聪:visual studio 2017编译运行出现脚本发生错误等问题如何解决?
    黄聪:xampp启动后mysql报Error
    黄聪:公众号怎么用微信做出点击此处查看答案
    黄聪:保持web页面生成的app一直处于用户登录状态不退出
    黄聪: $(document).click() 在iphone上不触发事件解决办法
    黄聪:bootstrap的模态框modal插件在苹果iOS Safari下光标偏离问题解决方案
    黄聪:pjax使用心得总结
    黄聪:Pjax无刷新跳转页面实现,支持超链接与表单提交
    黄聪:Pjax 无刷新开发web,更好用户体验
  • 原文地址:https://www.cnblogs.com/makejeffer/p/5031272.html
Copyright © 2011-2022 走看看