图论----深度优先遍历和广度优先遍历

来源:互联网 发布:搞笑网络证件在线制作 编辑:程序博客网 时间:2024/05/14 03:27

1、广度优先遍历

        广度优先遍历从某个顶点v出发,首先访问这个结点,并将其标记为已访问过;

        然后顺序访问结点v的所有未被访问的邻接点{vi,..,vj},并将其标记为已访问过;

        然后将{vi,...,vj}中的每一个节点重复节点v的访问方法,直到所有结点都被访问完为止。

具体代码实现时:我们可以使用一个辅助队列q,首先将顶点v入队,然后循环检测队列是否为空,

2、深度优先遍历

        深度优先遍历首先从某个顶点v出发,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点均已被访问为止。

3、两种遍历的非递归代码如下:

#include "stdafx.h"#include <iostream.h>#include <stdlib.h>#include <queue>#include <stack>using namespace std;const int n=9;//广度优先遍历void BFS(int a[][n]){//label数组标记访问元素int label[n+1];for (int j=0;j<=n;j++)label[j]=0;queue<int> q;q.push(0);label[0]=1;  //标记已访问元素//队列不为空while(!q.empty()){int key=q.front();cout<<key<<" ";q.pop();//将与key节点相关联的未访问的节点入队for (int i=0;i<n;i++){if (a[key][i]!=0&&label[i]==0){q.push(i);label[i]=1; //标记已访问元素}}}cout<<endl;}//元素入栈,并标记已访问元素,同时更新flagvoid PushNode(int a[][n],stack<int> s,int *label,int &key,int &flag){for (int i=0;i<n;i++){flag=key;if (a[key][i]!=0&&label[i]==0){s.push(i);  label[i]=1;key=i;break;}}}//广度优先遍历void DFS(int a[][n]){//label数组标记访问元素int *label=new int[n+1];for (int j=0;j<=n;j++)label[j]=0;stack<int> s;int key=0;int flag=-1;  //用flag变量判断是否已经遍历到最底端s.push(key);label[key]=1;while(!s.empty()){//未遍历到图的最深处if(key!=flag){cout<<key<<" "; PushNode(a,s,label,key,flag);}//遍历到图的最深处else{key=s.top();s.pop();PushNode(a,s,label,key,flag);}}cout<<endl;delete label;}int main(int argc, char* argv[]){//邻接矩阵9*9,节点0~8int a[n][n]={1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,1,1,1,0,0,1,1,0,1,1,0,1,0,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1,0,1,1,0,1,1,0,0,1,1,1,1};cout<<"广度优先遍历:";BFS(a);cout<<"深度优先遍历:";DFS(a);return 0;}

 

 

原创粉丝点击