前言
最近在看算法,拜读了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:截图如下