数据结构基础 图的遍历(三) 之 BFS+DFS(非递归实现)

本文介绍了图的遍历,包括广度优先搜索(BFS)和深度优先搜索(DFS)的非递归实现。通过示例代码展示了这两种遍历方法,并提供了拓扑排序的列表。在VS2010中,需要注意无返回值函数的编译问题。深度优先搜索的非递归实现借助了栈的思想,而广度优先搜索则利用了队列。
摘要由CSDN通过智能技术生成

【图例】










【屌丝代码】

#include<iostream>  
#include<vector>  
#include<queue>  
#include<list>  
#include<stack>  
#include<string>  
  
using namespace std;  
  
class Graph  
{  
private:  
 int V; //顶点数  
 int *indegree; // 入度数链表  
 queue< int > q; // 入度为 0 队列  
 list< int > *adj; // 出度表  
public:  
 Graph(int V);  
      ~Graph();  
 void AddEdge(int v,int w);  
 bool TopoSort();  
 void BFS();  
 void DFS();  
};  
  
Graph::Graph(int V=10)  
{  
 this->V = V;  
 adj = new list<int>[V];  
 indegree = new int[V];  
 for (int i=0;i<V;i++)  
      {  
          indegree[i] = 0;  
      }  
}  
Graph::~Graph()  
{  
 delete []indegree;  
 delete []adj;  
}  
void Graph::AddEdge(int v,int w)  
{  
 indegree[w]++;
 adj[v].push_back(w);
}  
bool Graph::TopoSort()  
{  
 int data,count(0);  
 for(int i = 0;i<V;i++)  
          if(indegree[i] == 0)  
              q.push(i);  
 while(!q.empty())  
      {  
          data = q.front();  
          q.pop();  
          count++;  
          cout<<data<<"\t";  
          list<int>::iterator it = adj[data].begin();  
          for(;it!=adj[data].end();it++)  
          {  
              indegree[*it]--;  
              if(indegree[*it] == 0)  
                  q.push(*it);  
          }  
      }  
 cout<<endl;  
 if(count<V)  
          return false;  
 else  
          return true;  
}  
void Graph::BFS()  
{  
 cout<<"广度优先遍历!!! "<<endl;  
 int *visited = new int[V];  
 int i;  
 for(i=0;i<V;i++)  
      {  
          visited[i] = 0;  
      }  
 for(i=0;i<V;i++)  
          if(visited[i] == 0)  
          {  
              visited[i] = 1;          
              queue<int> q;  
              q.push(i);  
              while(!q.empty())  
              {  
                  int tmp = q.front();  
                  q.pop();  
                  cout<<tmp<<"\t";  
                  list<int>::iterator it = adj[tmp].begin();  
                  for(;it!=adj[tmp].end();it++)  
                  {  
                      if(visited[*it] == 0)  
                      {  
                          q.push(*it);  
                          visited[*it] = 1;  
                      }  
                  }  
              }  
         }  
}  
void Graph::DFS()  
{  
 cout<<endl;  
 cout<<"深度优先遍历!!! "<<endl;  
 int *visited = new int[V];  
 int i,tmpv,flag;  
 list<int> *tmpadj = adj;  
 stack<int> s;  
 for(i=0;i<V;i++)  
      {  
          visited[i] = 0;  
      }  
 for(i=0;i<V;i++)  
      { 
          if(visited[i] == 0)  
          {  
              visited[i] = 1;  
              s.push(i);  
              cout<<i<<"\t";  
              while(!s.empty())  
              {               
                  if(tmpadj[s.top()].size()>0)  
                  {               
                      // cout<<tmpadj[s.top()].size()<<endl;  
                      list<int>::iterator it = tmpadj[s.top()].begin();  
                      flag = 0;  
                      for(;it!=tmpadj[s.top()].end();it++)  
                      {  
                          if(visited[*it] == 0)  
                          {  
                              flag = 1;  
                              break;               
                          }
                      }  
                      if(flag == 1)  
                      {  
                          // cout<<*it<<endl;  
                          tmpv = *it;  
                          tmpadj[s.top()].erase(it);
                          // cout<<*it<<endl;  
                          s.push(tmpv);
                          cout<<s.top()<<"\t";  
                          visited[s.top()] = 1;  
                          // cout<<s.top()<<endl;  
                          // cout<<s.top()<<endl;  
                      }  
                      else  
                      {  
                          s.pop();  
                      }  
                  }  
                  else  
                  {  
                      // cout<<s.top()<<endl;  
                      s.pop();  
                  }  
              }  
          }  
      }  
}  
int main()  
{  
 Graph myg(9);  
 myg.AddEdge(0,1);  
 myg.AddEdge(0,3);  
 myg.AddEdge(0,4);  
 myg.AddEdge(1,2);  
 myg.AddEdge(1,5);  
 myg.AddEdge(2,5);  
 myg.AddEdge(0,6);  
 myg.AddEdge(0,7);  
 myg.AddEdge(1,8);  
    
 cout<<"TOPOSORT LIST"<<endl;  
 myg.TopoSort();  
//   cout<<myg.TopoSort()<<endl;  
 myg.BFS();  
 myg.DFS();  
 return 0;  
}

 

【运行结果】

TOPOSORT LIST

0       1       3       4       6       7       2       8       5    

广度优先遍历!!!                                                      

0       1       3       4       6       7       2       5       8    

深度优先遍历!!!                                                      

0       1       2       5       8       3       4       6       7               

【备注与小结】

1.VS2010不承认无返回值函数,【AddEdge(int v,int w);】函数在VC6.0中编译可以通过,但是,在VS2010中,【void AddEdge(int v,int w);】才能编译通过;

2.广度优先遍历一个自定义函数就能直接解决,但是,采用迭代递归实现深度优先遍历要比直接使用while循环要简单得多,诚然如此,但本文屌丝代码给出的是自己为了仿真递归机制实现的;

3.广度优先直接使用队列实现即可,采用单函数实现深度优先是栈实现;

4.深度优先搜索双弹栈机制,是在仿迭代上十分重要的思想,也是使用非递归实现深度搜索的重中之重。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值