0 图的遍历
图的遍历图和树的遍历类似,那就是从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这个过程就叫做图的遍历。
对于图的遍历来说,如何避免因回路陷入死循环,就需要科学地设计遍历方案,通过有两种遍历次序方案:深度优先遍历和广度优先遍历。
1 DFS算法思想
深度优先遍历(Depth_First_Search),也称为深度优先搜索,简称DFS。
2 BFS算法思想
广度优先遍历(Breadth_First_Search),又称为广度优先搜索,简称BFS。
3 代码实现
//Graph header file.
#ifndef _GRAPH_H
#define _GRAPH_H
#include "cComHead.h"
#if Graph_dfsbfs_ctrol
#include <iostream>
#include <cstdio>
#include <list>
#include <vector>
#include <queue>
#include <stack>
#include <fstream>
using namespace std;
template <class T>
class graph
{
private:
T n;
vector<list<T>> _graph;
bool visited[100] = {0};
/* data */
public:
graph(/* args */);
~graph();
//Creat graph
void creatGraph();
void creatGraph(const char*);
//DFS Recursion
void dfs(const T&);
//DFS no Recursion
void dfs_noRec(const T&);
//BFS no Recursion
void bfs_noRec(const T&);
};
template <class T>
graph<T>::graph(/* args */)
{
}
template <class T>
graph<T>::~graph()
{
}
#endif
#endif /*graph.h*/
- 代码中采用邻接表的方式存储图,定义形式为
vector<list<T>>
. - 创建图采用了两种方式,一种是手动输入数据
creatGraph()
,另一种是文本方式导入数据creatGraph(const char*)
。具体实现方法如下:
template <class T>
void graph<T>::creatGraph()
{
cout << "input the vertex num:" << endl;
cin >> n;
//vector<list<T>>::iterator it;
for (int i = 0; i < n; ++i)
{
list<T> i1;
T t;
while (cin >> t && t != n) //输入每个顶点相连的图,以最终节点为结束标志
i1.push_back(t);
_graph.push_back(i1);
}
}
template <class T>
void graph<T>::creatGraph(const char *fp)
{
ifstream in(fp);
in >> n;
cout << "input the vertex num:" << n << endl;
for (int i = 0; i < n; i++)
{
/* code */
list<T> i1;
T t;
while (in >> t && t != n) //输入每个顶点相连的图,以最终节点为结束标志
i1.push_back(t);
_graph.push_back(i1);
}
}
- 广度优先BFS算法采用非递归方式实现
void bfs_noRec(const T&)
,借助了队列,具体实现方法如下:
template <class T>
void graph<T>::bfs_noRec(const T &ver)
{
visited[ver] = true;
cout << ver << "-->";
queue<T> myqueue;
myqueue.push(ver);
while (!myqueue.empty())
{
/* code */
T tempver = myqueue.front();
myqueue.pop();
for (auto it : _graph[tempver])
{
/* code */
if (!visited[it])
{
cout << it << "-->";
myqueue.push(it);
visited[it] = true;
}
}
}
cout << "end!" << endl;
}
- 深度优先DFS算法采用递归和非递归两种方式实现
void dfs(const T&)
、void dfs_noRec(const T&)
,其中非递归方式借助了栈,具体实现方法如下:
template <class T>
void graph<T>::dfs(const T &ver)
{
visited[ver] = true;
cout << ver << "-->";
for (auto it : _graph[ver])
{
/* code */
if (!visited[it])
dfs(it);
}
}
template <class T>
void graph<T>::dfs_noRec(const T &ver)
{
visited[ver] = true;
cout << ver << "-->";
stack<T> mystack;
mystack.push(ver);
while (!mystack.empty())
{
/* code */
T tempver = mystack.top();
mystack.pop();
if (!visited[tempver])
{
visited[tempver] = true;
cout << tempver << "-->";
}
for (auto it : _graph[tempver])
{
/* code */
if (!visited[it])
mystack.push(it);
}
}
cout << "end!" << endl;
}
4 测试
int main(int argc, char *argv[])
{
#if Graph_dfsbfs_ctrol
graph<int> mygraph, mygraph1;
mygraph.creatGraph("testdata.txt");
mygraph1.creatGraph("testdata.txt");
mygraph.bfs_noRec(0);
mygraph1.dfs(0);
cout << "end!" << endl;
#endif
}
博主在测试中才用了文本导入数据的方式,testdata.txt
中存放测试数据,数据列表如下:
8
0 1 2 8
1 0 3 4 8
2 0 5 6 8
3 1 7 8
4 1 7 8
5 2 7 8
6 2 7 8
7 3 4 5 6 8