深度优先遍历算法--非递归实现
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:截图如下
相关文章推荐
- 图的深度优先遍历算法的递归与非递归JAVA实现
- 深度优先遍历算法的非递归实现
- 生成迷宫的深度优先遍历算法的非递归实现
- 深度优先遍历算法的非递归实现
- [原创]如何用栈实现递归与非递归的转换
- 递归实现简易的资源管理器
- 前序、中序、后序遍历的多种非递归实现
- c++实现二叉树层序、前序创建二叉树,递归非递归实现二叉树遍历
- 小程序:备考问题&递归实现每天备考时间的分配(含代码)
- 如何用栈实现递归与非递归的转换
- 递归实现汉诺塔原理及核心代码
- 递归实现1+2+3+...+n
- 二叉树深度优先(DFS)和广度优先(BFS)算法的非递归实现
- 利用递归巧妙实现组合
- MySQL函数实现递归查询子节点
- Java实现二叉树的遍历(递归和非递归)
- 递归实现1-9之间添加"+"或"-"或""使得运算结果为100
- 递归实现全排列算法
- 二叉树的递归非递归实现的中序遍历
- 多线程中递归锁的实现.