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;
}
//元素入栈,并标记已访问元素,同时更新flag
void 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~8
int 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;
}