数据结构基础(21) --DFS与BFS
来源:程序员人生 发布时间:2015-02-26 21:00:59 阅读次数:3218次
DFS
从图中某个顶点V0 动身,访问此顶点,然后顺次从V0的各个未被访问的邻接点动身深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈).
//使用邻接矩阵存储的无向图的深度优先遍历
template <typename Type>
void Graph<Type>::DFS()
{
stack<int> iStack;
showVertex(0);
vertexList[0]->wasVisted = true;
iStack.push(0);
while (!iStack.empty())
{
int top = iStack.top();
int v = getAdjUnvisitedVertex(top);
if (v == ⑴)
{
iStack.pop();
}
else
{
showVertex(v);
vertexList[v]->wasVisted = true;
iStack.push(v);
}
}
//使其还可以再深/广度优先搜索
for (int i = 0; i < nVerts; ++i)
vertexList[i]->wasVisted = false;
}
BFS
从图中的某个顶点V0动身,并在访问此顶点以后顺次访问V0的所有未被访问过的邻接点,以后按这些顶点被访问的前后次序顺次访问它们的邻接点,直至图中所有和V0有路径相通的顶点都被访问到.
若此时图中尚有顶点未被访问,则另选图中1个未曾被访问的顶点作起始点,重复上述进程,直至图中所有顶点都被访问到为止(使用队列)。
//使用邻接矩阵存储的无向图的广度优先遍历
template <typename Type>
void Graph<Type>::BFS()
{
queue<int> iQueue;
showVertex(0);
vertexList[0]->wasVisted = true;
iQueue.push(0);
while (!iQueue.empty())
{
int front = iQueue.front();
iQueue.pop();
int v = getAdjUnvisitedVertex(front);
while (v != ⑴)
{
showVertex(v);
vertexList[v]->wasVisted = true;
iQueue.push(v);
v = getAdjUnvisitedVertex(front);
}
}
for (int i = 0; i < nVerts; ++i)
vertexList[i]->wasVisted = false;
}
附-完全代码
const int MAX_VERTS = 20;
//顶点
template <typename Type>
class Vertex
{
public:
Vertex(const Type &_node = Type())
: node(_node), wasVisted(false) {}
public:
bool wasVisted; //增加1个访问位
Type node;
};
//图
template <typename Type>
class Graph
{
public:
Graph();
~Graph();
void addVertex(const Type &vertex);
void addEdge(int start, int end);
void printMatrix();
void showVertex(int v);
void DFS();
void BFS();
private:
int getAdjUnvisitedVertex(int v);
private:
Vertex<Type>* vertexList[MAX_VERTS];
int nVerts;
int adjMatrix[MAX_VERTS][MAX_VERTS];
};
template <typename Type>
void Graph<Type>::DFS()
{
stack<int> iStack;
showVertex(0);
vertexList[0]->wasVisted = true;
iStack.push(0);
while (!iStack.empty())
{
int top = iStack.top();
int v = getAdjUnvisitedVertex(top);
if (v == ⑴)
{
iStack.pop();
}
else
{
showVertex(v);
vertexList[v]->wasVisted = true;
iStack.push(v);
}
}
//使其还可以再深度优先搜索
for (int i = 0; i < nVerts; ++i)
vertexList[i]->wasVisted = false;
}
template <typename Type>
void Graph<Type>::BFS()
{
queue<int> iQueue;
showVertex(0);
vertexList[0]->wasVisted = true;
iQueue.push(0);
while (!iQueue.empty())
{
int front = iQueue.front();
iQueue.pop();
int v = getAdjUnvisitedVertex(front);
while (v != ⑴)
{
showVertex(v);
vertexList[v]->wasVisted = true;
iQueue.push(v);
v = getAdjUnvisitedVertex(front);
}
}
for (int i = 0; i < nVerts; ++i)
vertexList[i]->wasVisted = false;
}
//获得下1个还没有访问的连通节点
template <typename Type>
int Graph<Type>::getAdjUnvisitedVertex(int v)
{
for (int j = 0; j < nVerts; ++j)
{
//首先是邻接的, 并且是未访问过的
if ((adjMatrix[v][j] == 1) &&
(vertexList[j]->wasVisted == false))
return j;
}
return ⑴;
}
//打印节点信息
template <typename Type>
void Graph<Type>::showVertex(int v)
{
cout << vertexList[v]->node << ' ';
}
template <typename Type>
Graph<Type>::Graph():nVerts(0)
{
for (int i = 0; i < MAX_VERTS; ++i)
for (int j = 0; j < MAX_VERTS; ++j)
adjMatrix[i][j] = 0;
}
template <typename Type>
Graph<Type>::~Graph()
{
for (int i = 0; i < nVerts; ++i)
delete vertexList[i];
}
template <typename Type>
void Graph<Type>::addVertex(const Type &vertex)
{
vertexList[nVerts ++] = new Vertex<Type>(vertex);
}
template <typename Type>
void Graph<Type>::addEdge(int start, int end)
{
//无向图
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}
template <typename Type>
void Graph<Type>::printMatrix()
{
for (int i = 0; i < nVerts; ++i)
{
for (int j = 0; j < nVerts; ++j)
cout << adjMatrix[i][j] << ' ';
cout << endl;
}
}
//测试代码
int main()
{
Graph<char> g;
g.addVertex('A'); //0
g.addVertex('B'); //1
g.addVertex('C'); //2
g.addVertex('D'); //3
g.addVertex('E'); //4
g.addEdge(0, 1); //A-B
g.addEdge(0, 3); //A-D
g.addEdge(1, 0); //B-A
g.addEdge(1, 4); //B-E
g.addEdge(2, 4); //C-E
g.addEdge(3, 0); //D-A
g.addEdge(3, 4); //D-E
g.addEdge(4, 1); //E-B
g.addEdge(4, 2); //E-C
g.addEdge(4, 3); //E-D
g.printMatrix();
cout << "DFS: ";
g.DFS();
cout << "
BFS: ";
g.BFS();
return 0;
}
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠