1、图的遍历(DFS)
深度优先(DFS)
深度优先算法
-原料: class LinkStack< T>;- 步骤
1. 将起始顶点压入栈中
2. 弹出栈顶顶点V, 判断是否已经标记(标记:转2, 未标记:转3)
3. 标记顶点,并将顶点v的邻接顶点压入栈中
4 判断栈是否为空(非空: 转2, 空:结束) 深度优先算法示例
2、编程实验
深度优先算法 Graph::DFSGraph.h
新增
- SharedPointer< Array<int> > DFS(int i)
- {
- DynamicArray<int>* ret = NULL;
- if((0 <= i)&&(i < vCount()))
- {
- LinkStack<int> s;
- LinkQueue<int> r;
- DynamicArray<bool> visited(vCount());
- for(int j=0;j<visited.length();j++)
- {
- visited[j] = false;
- }
- s.push(i);
- while(s.size() > 0)
- {
- int v = s.top();
- s.pop();
- if( !visited[v] )
- {
- SharedPointer< Array<int> > aj = getAdjacent(v);
- for(int j=aj->length()-1;j>=0;j--)
- {
- s.push((*aj)[j]); //最先获取到的邻接顶点最后入栈,最先出栈
- }
- r.add(v);
- visited[v] = true;
- }
- }
- ret = toArray(r);
- }
- else
- {
- THROW_EXCEPTION(NoEnoughMemoryException,"Index i is invalid ...");
- }
- return ret;
- }
main.cpp
- #include <iostream>
- #include "MatrixGraph.h"
- using namespace std;
- using namespace DTLib;
- int main()
- {
- MatrixGraph<9,char,int> g;
- const char* VD = "ABEDCGFHI";
- for(int i=0;i<9;i++)
- {
- g.setVertex(i,VD[i]);
- }
- g.setEdge(0,1,0);
- g.setEdge(1,0,0); //有向图表示无向图,权值0代表无权值
- g.setEdge(0,3,0);
- g.setEdge(3,0,0);
- g.setEdge(0,4,0);
- g.setEdge(4,0,0);
- g.setEdge(1,2,0);
- g.setEdge(2,1,0);
- g.setEdge(1,4,0);
- g.setEdge(4,1,0);
- g.setEdge(2,5,0);
- g.setEdge(5,2,0);
- g.setEdge(3,6,0);
- g.setEdge(6,3,0);
- g.setEdge(4,6,0);
- g.setEdge(6,4,0);
- g.setEdge(6,7,0);
- g.setEdge(7,6,0);
- g.setEdge(7,8,0);
- g.setEdge(8,7,0);
- SharedPointer< Array<int> > sa = g.DFS(0);
- for(int i=0;i<sa->length();i++)
- {
- cout << (*sa)[i] << " ";
- }
- return 0;
- }
3、问题
如何使用二叉树先序遍历的思想遍历图?4、递归版深度优先
G = v0 + G'
DFS(G) = visited(v0) + DFS(G')
G'不为空,且v0到G'有连接
- 定义功能: DFS(graph, vex)
以顶点vex为起始顶点深度优先遍历graph
5、编程实验
递归版深度优先算法 DFS(graph, vex)
- #include <iostream>
- #include "MatrixGraph.h"
- using namespace std;
- using namespace DTLib;
- template < typename V, typename E >
- void DFS(Graph<V, E>& g, int v, Array<bool>& visited)
- {
- if((0 <= v)&&(v < g.vCount()))
- {
- cout<< v <<endl;
- visited[v] = true;
- SharedPointer< Array<int> > aj = g.getAdjacent(v);
- for(int i=0;i<aj->length();i++) //v没有邻接顶点就不会递归调用
- {
- if( !visited[(*aj)[i]])
- {
- DFS(g, (*aj)[i], visited);//从邻接顶点开始深度优先遍历子图
- }
- }
- }
- else
- {
- THROW_EXCEPTION(InvalidParameterException,"Index v is invalid ...");
- }
- }
- template < typename V, typename E >
- void DFS(Graph<V, E>& g, int v)
- {
- DynamicArray<bool> visited(g.vCount());
- for(int i=0;i<visited.length();i++)
- {
- visited[i] = false;
- }
- DFS(g, v, visited);
- }
- int main()
- {
- MatrixGraph<9,char,int> g;
- const char* VD = "ABEDCGFHI";
- for(int i=0;i<9;i++)
- {
- g.setVertex(i,VD[i]);
- }
- g.setEdge(0,1,0);
- g.setEdge(1,0,0); //有向图表示无向图,权值0代表无权值
- g.setEdge(0,3,0);
- g.setEdge(3,0,0);
- g.setEdge(0,4,0);
- g.setEdge(4,0,0);
- g.setEdge(1,2,0);
- g.setEdge(2,1,0);
- g.setEdge(1,4,0);
- g.setEdge(4,1,0);
- g.setEdge(2,5,0);
- g.setEdge(5,2,0);
- g.setEdge(3,6,0);
- g.setEdge(6,3,0);
- g.setEdge(4,6,0);
- g.setEdge(6,4,0);
- g.setEdge(6,7,0);
- g.setEdge(7,6,0);
- g.setEdge(7,8,0);
- g.setEdge(8,7,0);
- SharedPointer< Array<int> > sa = g.DFS(0);
- for(int i=0;i<sa->length();i++)
- {
- cout << (*sa)[i] << " ";
- }
- DFS(g, 0);
- return 0;
- }
6、小结
深度优先按照“先序遍历的方式”对顶点进行访问
深度优先算法的核心是栈的使用
深度优先和广度优先的唯一不同在于栈或队列的使用
深度优先算法可以使用递归的方式实现