您的位置:首页 > 其它

广度优先搜索和深度优先搜索

2015-08-22 13:10 239 查看
DBF深度优先搜索,最经典的方法,可以使用递归来实现。

结构体定义

typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define INFINITE 65535
typedef struct
{
VertexType vexs[MAXVEX];	//顶点表
EdgeType arc[MAXVEX][MAXVEX];	//邻接矩阵
int numVertexes,numEdges;
}MGraph;


测试函数如下

MGraph graph;
graph.numVertexes = 9;
graph.numEdges = 14;
graph.vexs[0] = 'A';
graph.vexs[1] = 'B';
graph.vexs[2] = 'C';
graph.vexs[3] = 'D';
graph.vexs[4] = 'E';
graph.vexs[5] = 'F';
graph.vexs[6] = 'G';
graph.vexs[7] = 'H';
graph.vexs[8] = 'I';

for (int i = 0;i<MAXVEX;i++)
for (int j= 0;j<MAXVEX;j++)

{
graph.arc[i][j] = INFINITE;
}
graph.arc[0][1] = graph.arc[1][0] = 1;
graph.arc[0][5] = graph.arc[5][0] = 1;
graph.arc[1][2] = graph.arc[2][1] = 1;
graph.arc[1][8] = graph.arc[8][1] = 1;
graph.arc[1][6] = graph.arc[6][1] = 1;
graph.arc[2][8] = graph.arc[8][2] = 1;
graph.arc[2][3] = graph.arc[3][2] = 1;
graph.arc[3][8] = graph.arc[8][3] = 1;
graph.arc[5][6] = graph.arc[6][5] = 1;
graph.arc[4][5] = graph.arc[5][4] = 1;
graph.arc[6][7] = graph.arc[7][6] = 1;
graph.arc[4][7] = graph.arc[7][4] = 1;
graph.arc[3][7] = graph.arc[7][3] = 1;
graph.arc[3][6] = graph.arc[6][3] = 1;

printf("DFS by recursion\n");
solu.DeepthFirstSearch(graph);

printf("\nDFS by Stack\n");
solu.DeepthFirstSearch_Stack(graph);

printf("\nBFS by Quene\n");
solu.BreadthFirstSearch(graph);


用递归实现的代码如下

int visited[MAXVEX];
void DFS(MGraph graph, int i)
{
printf("%c ",graph.vexs[i]);
visited[i]=1;
for (int j = 0;j<graph.numVertexes;j++)
{
if (graph.arc[i][j]!=INFINITE && visited[j]==0)
{
DFS(graph,j);
}
}
}

void DeepthFirstSearch(MGraph graph)
{
for (int i = 0;i<graph.numVertexes;i++)
{
visited[i] = 0;//未被访问
}
for (int i = 0; i<graph.numVertexes; i++)
{
if (visited[i] == 0)
{
DFS(graph,i);
}
}
}


同样也可以使用栈来实现

void DeepthFirstSearch_Stack(MGraph graph)
{
for (int i = 0;i<graph.numVertexes;i++)
{
visited[i] = 0;//未被访问
}
stack<int> stackDFS;
for (int i = 0; i<graph.numVertexes; i++)
{
if (visited[i] == 0)
{
visited[i] = 1;
stackDFS.push(i);

while (!stackDFS.empty())
{
int k = stackDFS.top();
visited[k] = 1;
printf("%c ",graph.vexs[k]);
stackDFS.pop();
for (int j = 0; j<graph.numVertexes ;j++)
{
if (graph.arc[k][j] != INFINITE && visited[j] == 0)
{
visited[j] = 1;
stackDFS.push(j);
}
}
}
}
}
}


而广度优先搜索可以使用队列来实现

void BreadthFirstSearch(MGraph graph)
{
for (int i = 0;i<graph.numVertexes;i++)
{
visited[i] = 0;//未被访问
}
queue<int> QueueBFS;
for (int i = 0;i<graph.numVertexes;i++)
{
if (visited[i] == 0)
{
visited[i] = 1;
QueueBFS.push(i);

while (!QueueBFS.empty())
{
int k = QueueBFS.front();
printf("%c ",graph.vexs[k]);

QueueBFS.pop();
for (int j = 0;j<graph.numVertexes;j++)
{
if (graph.arc[k][j] != INFINITE && visited[j] == 0)
{
visited[j] = 1;
QueueBFS.push(j);
}
}
}
}
}
}


运行结果如下图



可以看到,二者代码几乎一毛一样。区别在于DFS使用了栈,BFS使用的是队列。其实结合DFS和BFS的特点也很好理解,从树的角度思考,BFS希望先找到左右的子节点,希望按照这个顺序来打印,所以就是先进先出,也就是队列。而DFS则希望先顺着某条线一直打印,希望后进的先打印出来,也就是栈。

注意,两种DFS打印结果是不一样的,但是都是DFS。

最后需要注意的是,用栈和队列写这两个算法时,打印的位置很重要,自己写容易出错,不知道是在visit[i]=1的时候就打印还是出队列的时候打印。其实很简单,我们利用的就是栈和队列的特色,所以出栈和出队列的时候打印就没有问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: