图的深度优先遍历和广度优先遍历

来源:互联网 发布:网络直播相关法律出台 编辑:程序博客网 时间:2024/06/05 03:52

图有无向图和有向图,无向图的遍历可以从任意一点开始都能完成对图的遍历

有向图则需要合适的图和合适的起点才能完成遍历。如果一个节点光有出度而没有入度,不从这个节点出发就遍历不到这个节点也就不能完成对整个图的遍历,比如说没有父节点地址的树的根。

遍历的方式有宽度优先遍历(bfs)和深度优先遍历(dfs)。


宽度优先遍历(bfs):

只大致描述一下遍历方式,图的宽度优先遍历首先从一个节点开始,类似于树的层次遍历,先遍历掉这个节点的没有被遍历过的全部直接有边相连通的节点后再遍历更深的节点。

在上图中假设从1开始遍历则顺序为:1,2,3,4,7,5,6.

算法步骤借助队列实现。

深度优先遍历(dfs):

图的深度优先遍历从一个节点开始,优先考虑深度,如果看成是树的话就是先遍历完孩子节点再遍历兄弟节点。

在上面的图中依旧假设从1节点开始则遍历顺序为:1,2,7,3,4,5,6。

代码:

#include<iostream>#include<queue>#include<set>#include<cstring>using namespace std;#define mem(a) memset(a,0,sizeof(a))#define MaxN 300+5struct node{   int num;   set<node*> connect; //通过邻接链表存放图}Node[MaxN];bool search[MaxN];void bfs(node* pointer){   if(pointer==NULL){      return;   }   /*输入预期遍历过程中将要进行的操作  这里以输出节点编号为例*/   cout<<pointer->num<<' ';   search[pointer->num]=true;   /*操作截止线*/   for(set<node*>::iterator i=pointer->connect.begin();i!=pointer->connect.end();i++){      if(search[(*i)->num]!=true){         bfs(*i);      }   }}void dfs(node* pointer){   if(pointer==NULL){      return;   }   queue<node*> p;   node* temp;   p.push(pointer);   while(!p.empty()){      temp=p.front();      p.pop();      if(search[temp->num]==true){         continue;      }      /*进行预期遍历过程中想要进行的操作 这里假设为输出节点的编号*/      cout<<temp->num<<' ';      search[temp->num]=true;      /*操作截止线*/      for(set<node*>::iterator i=temp->connect.begin();i!=temp->connect.end();i++){         if(search[(*i)->num]!=true){            p.push(*i);         }      }   }}int main(){   int NodeN,EdgeN;   cout<<"input node number and edge number"<<endl;   cin>>NodeN>>EdgeN;   for(int i=1;i<=NodeN;i++){      Node[i].num=i;   }   int a,b;   cout<<"input all The edge of the information"<<endl;   for(int i=0;i<EdgeN;i++){ //统计边的信息      cin>>a>>b;      Node[a].connect.insert(Node+b);      Node[b].connect.insert(Node+a);   }   cout<<"bfs:"<<endl;   mem(search);   bfs(Node+1);   cout<<endl<<"dfs:"<<endl;   mem(search);   dfs(Node+1);}

这里假设图是以邻接链表的方式存储的


原创粉丝点击