您的位置:首页 > 其它

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

2013-07-09 18:46 141 查看


前言

最近在看算法,拜读了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,入栈,继续往深的方向的查找;

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

#include <iostream>
using namespace std;
#define maxnum 100         //定义邻接矩阵的最大定点数
int visited[maxnum] ;      //该数组用来表示顶点是否被访问过,true:已访问过 false : 未访问
int e[maxnum][maxnum];       //用来存储图中的边信息
int stacks[maxnum] = {-1};       //用来存储访问过的顶点。//无向图图的邻接矩阵表示
struct graph

 char v[maxnum] ;    //图的顶点信息 
 int vnums;         //顶点个数 
 int enums;        //边的个数 
 graph(int v,int e):vnums(v),enums(e){}
};

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

//深度优先遍历图
void DFS(graph& g , int v) 
{  
       for(int i = 1 ; i <= g.vnums; i++)    
//数组从1开始遍历
            visited[i] = false;         //对visited数组进行初始化,即表示所有顶点都没有被访问过 
       cout << " v"<<v; 
       int top = -1; 
       visited[v] = true; 
       stacks[++top] = v;       //将顶点v入栈 
        while(top !=-1) 
        { 
            v = stacks[top];      //取栈顶元素 
            int tmp = 0; 
            for(int i = 1 ; i <= g.vnums; i++) 
            {
                if( e[v][i] == 1 && !visited[i])
               {   
                   cout << " v" << i;       //找到一个未访问的顶点就马上退出循环,同时将找到的顶点入栈 
                   visited[i] = true; 
                   stacks[++top] = i; 
                   break;
               }
               tmp = i; 
           }   //for循环结束
         if( tmp >= g.vnums)        //当没有了未访问顶点之后,tmp的值就成了g.vnums,此时需要出栈, 
            top--;                            //进行回溯,回溯到节点v之后继续循环  
      }    //while循环结束
}
int main()
{
       graph g(5,5);
       creategraph(g); 
       DFS(g,1); 
       return 0 ;
}

// 测试数据 

 // 输入边的头和尾

// 1 2

// 1 3

// 1 4

 // 3 4

// 4 5

//输出

// v1 v2 v3 v4 v5

PS:截图如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法