深度优先遍历算法--非递归实现

13 篇文章 1 订阅


前言

最近在看算法,拜读了CSDN大神的博文,深感大神就是犀利,只能膜拜了。同时为了与我的健忘症对斗争,有必要将学到的东西记下来。

在图算法中,广度优先遍历算法和深度优先遍历算法是比较重要的算法,同时也是比较基础的搜索算法。

算法思想

 广度优先遍历算法( Breadth-First Search) :在给定图 G = ( V , E ) 和一个特定的源顶点s的情况下,BFS系统的查找图G中的边,希望发现可从s到达的所有顶点,并计算s到所有这些可达顶点之间的距 ( 即最少的变数 )。算法会首先发现和s距离为 k (k = 1,2 ,3 ... ) 的所有顶点,然后才会发现和s距离为 k+1 ( k= 1 ,2, 3...) 的其他顶点。

 深度优先遍历算法 ( Depth-First Search) :DFS所遵循的搜索策略是尽可能“深”地搜索一个图,一直到不能继续访问下去为止。对于最新发现的顶点,如果它还有以此为起点而未访问过的边,就继续沿此边继续探测下去。

DFS算法演示地址:点击链接


DFS算法非递归的思想:

DFS算法非递归需要用到一个栈 stack ( 将已访问过的顶点入栈,必要时出栈) , 一个bool 类型的数组visited (用来标记某个顶点是否被访问过) 。

大致步骤:

当从顶点v开始遍历图之前,需要先将该顶点入栈;

之后取栈顶元素,并设置为true,表示以访问过;同时还需要遍历与v相关的顶点;

若找到一个未访问过的顶点,则设为true,入栈,继续往深的方向的查找;

若没有找到未访问过的顶点,则出栈,重复上面的步骤

  1. #include <iostream>
  2. using namespace std;
  3. #define maxnum 100         //定义邻接矩阵的最大定点数
  4. int visited[maxnum] ;      //该数组用来表示顶点是否被访问过,true:已访问过 false : 未访问
  5. int e[maxnum][maxnum];       //用来存储图中的边信息
  6. int stacks[maxnum] = {-1};       //用来存储访问过的顶点。//无向图图的邻接矩阵表示
  7. struct graph
  8.  char v[maxnum] ;    //图的顶点信息 
  9.  int vnums;         //顶点个数 
  10.  int enums;        //边的个数 
  11.  graph(int v,int e):vnums(v),enums(e){}
  12. };

  13. //初始化无向图
  14. void creategraph(graph& g) 
  15.  {
  16.      for(int i = 1 ; i <= g.vnums ; i++)       //初始化图 。  初始化是从1开始的
  17.            for(int j = 1; j <= g.vnums; j++) 
  18.              e[i][j] = 0; 
  19.      cout << "输入边的头和尾" << endl;
  20.      int i, j; 
  21.       for(int k = 1 ; k <= g.enums; k++) 
  22.       { 
  23.             cin >> i >> j;      //对于无向图,边(i,j) 与边(j,i) 是同一条边,所以输入的i,j需要存两次。 
  24.             e[i][j] = 1;         //如果是有向边,则只需要存一次就行了。 
  25.             e[j][i] = 1; 
  26.        }
  27. }

  28. //深度优先遍历图
  29. void DFS(graph& g , int v) 
  30. {  
  31.        for(int i = 1 ; i <= g.vnums; i++)     //数组从1开始遍历
  32.             visited[i] = false;         //对visited数组进行初始化,即表示所有顶点都没有被访问过 
  33.        cout << " v"<<v; 
  34.        int top = -1; 
  35.        visited[v] = true; 
  36.        stacks[++top] = v;       //将顶点v入栈 
  37.         while(top !=-1) 
  38.         { 
  39.             v = stacks[top];      //取栈顶元素 
  40.             int tmp = 0; 
  41.             for(int i = 1 ; i <= g.vnums; i++) 
  42.             {
  43.                 if( e[v][i] == 1 && !visited[i])
  44.                {   
  45.                    cout << " v" << i;       //找到一个未访问的顶点就马上退出循环,同时将找到的顶点入栈 
  46.                    visited[i] = true; 
  47.                    stacks[++top] = i; 
  48.                    break;
  49.                }
  50.                tmp = i; 
  51.            }   //for循环结束
  52.          if( tmp >= g.vnums)        //当没有了未访问顶点之后,tmp的值就成了g.vnums,此时需要出栈, 
  53.             top--;                            //进行回溯,回溯到节点v之后继续循环  
  54.       }    //while循环结束
  55. }
  56. int main()
  57. {
  58.        graph g(5,5);
  59.        creategraph(g); 
  60.        DFS(g,1); 
  61.        return 0 ;
  62. }


// 测试数据 

 // 输入边的头和尾

// 1 2

// 1 3

// 1 4

 // 3 4

// 4 5

//输出

// v1 v2 v3 v4 v5

PS:截图如下

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值