美文网首页
图-深度优先搜索与广度优先搜索

图-深度优先搜索与广度优先搜索

作者: 如春天 | 来源:发表于2020-08-10 14:42 被阅读0次

深度优先搜索(Depth First Search, DFS)

深度优先遍历图的方法是,从图中某顶点v出发:

(1)访问顶点v;

(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

可以看到这里面运用了递归的思想,下面给出了DFS算法基于邻接矩阵与邻接表的不同算法。对于基于邻接矩阵的算法,由于其是一个二维数组,要查找每个顶点的邻接点需要访问矩阵中的所有元素,因此其时间复杂度为O(n^2),而基于邻接表的DFS算法的时间复杂度则为O(n+e)。

基于邻接矩阵的DFS算法实现:

#include "邻接矩阵.h"
#define TRUE 1
#define FALSE 0
typedef int Boolean;
Boolean visited[MAXVEX];
void DFS(MGraph G, int i) {
    int j;
    visited[i] = TRUE;
    printf("%c", G.vexs[i]); /*输出访问顶点*/
    for(j = 0; j < G.numVertexes; j++){
        if(G.vexs[i][j] >= 1 && !visited[j]){
            /*为什么是>=1?因为可能是网,带有权值*/
            /*倘若(vi,vj)有边而且顶点j未被访问过则:*/
            DFS(G, j);
        }
    }
}
void DFSTraverse(MGraph G){
    int i;
    /*初始化visited数组,置所有顶点访问状态为FALSE*/
    for(i = 0; i < G.numVertexes; i++){
        visited[i] = FALSE;
    }
    for(i = 0; i < G.numVertexes; i++){
        /*对应连通图,这个循环只会执行一次,对于非连通图执行的次数为连通分量的个数,循环直到所有顶点都被访问。*/
        if(!visited[i]){
            DFS(G, i);
        }
    }
}

基于邻接表的DFS算法实现:

#include "邻接表.h"
#define TRUE 1
#define FALSE 0
typedef int Boolean;
Boolean visited[MAXVEX];
void DFS(GraphAdjList G, int i){
    EdgeNode * e;
    visited[i] = TRUE;
    printf("%c", G->adjList[i].data);
    e = G->adjList[i].firstEdge;
    while(e){
        if(!visited[e->adjVex]){
            DFS(G, e->adjVex);
        }
        e = e->next;
    }
}
void DFSTraverse(GraphAdjList G){
    int i;
    /*初始化visited数组,置所有顶点访问状态为FALSE*/
    for(i = 0; i < G->numVertexes; i++){
        visited[i] = FALSE;
    }
    for(i = 0; i < G->numVertexes; i++){
        /*对应连通图,这个循环只会执行一次,对于非连通图执行的次数为连通分量的个数,循环直到所有顶点都被访问。*/
        if(!visited[i]){
            DFS(G, i);
        }
    }
}

广度优先搜索(Breadth First Search, BFS)

1、把根节点放到队列的末尾。

2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。

3、找到所要找的元素时结束程序。

4、如果遍历整个树还没有找到,结束程序。 [1]

基于邻接矩阵的BFS算法实现:

#include "邻接矩阵.h"
#define TRUE 1
#define FALSE 0
typedef int Boolean;
Boolean visited[MAXVEX];
void BFSTraverse(MGraph G){
    int i, k, j;
    Queue Q;
    for(i = 0; i < G.numVertexes; i++){
        visited[i] = FALSE;
    }
    InitQueue(&Q);
    for(i = 0; i < G.numVertexes; i++){
        if(!visited[i]){
            visited[i] = TRUE;
            printf("%c", G.vexs[i]);
            Enqueue(&Q, i);
            while(!QueueEmpty(Q)){
                Dequeue(&Q, &k);/*队首出队赋给i*/
                /*判断其他所有顶点若与当前顶点存在边且未访问过*/
                for(j = 0; j < G.numVertexes; j++){
                    if(G.arc[k][j] >= 1 && visited[j]){
                        visited[j] = TRUE;
                        printf("%c", G.vexs[j]);
                        Enqueue(&Q, j);
                    }
                }
            }
        }
    }
}

基于邻接表的BFS算法实现:

#include "邻接表.h"
#define TRUE 1
#define FALSE 0
typedef int Boolean;
Boolean visited[MAXVEX];
void BFSTraverse(GraphAdjList G, int i){
    EdgeNode * e;
    int i, k;
    Queue Q;
    for(i = 0; i < G->numVertexes; i++){
        visited[i] = FALSE;
    }
    InitQueue(&Q);
    for(i = 0; i < G->numVertexes; i++){
        if(!visited[i]){
            visited[i] = TRUE;
            printf("%c", G->adjList[i].data);
            Enqueue(&Q, i);
            while(!QueueEmpty(Q)){
                Dequeue(&Q, &k);
                e = G->adjList[k].firstEdge;
                while(e){
                    if(!visited[e->adjvex]){
                        visited[e->adjvex] = TRUE;
                        printf("%c", G->adjList[e->adjvex].data);
                        Enqueue(&Q, e->adjvex);/*将此顶点入队*/
                    }
                    p = p->next;/*指向下一个邻接点*/
                }
            }
        }
    }
}

DFS BFS两者的区别举例说明

假设我们要在家里找某一样找不到的东西,我们会有很多种寻找的方案,如果我们采用深度优先搜索,就可以这样去理解:先到卧室,寻找柜子,再寻找搜索柜子里的抽屉,再寻找抽屉里的收纳盒。。。以此类推直到我们已经寻遍卧室的每一个角落。再去搜索书房。。。就类似于树的前序遍历。而对于广度优先算法我们可以这样理解:第一轮先搜索卧室的柜子、书房的柜子、客厅的柜子,第二轮寻找卧室的柜子里的抽屉、书房的柜子的抽屉、客厅的柜子的抽屉。。。以此类推。和树的层序遍历很相似。

相关文章

网友评论

      本文标题:图-深度优先搜索与广度优先搜索

      本文链接:https://www.haomeiwen.com/subject/yfljdktx.html