图的BFS与DFS算法在邻接矩阵与邻接表存储结构下实现

如题 自用笔记 如有错误欢迎及时指正

目录

一.广度优先搜索(BFS)

1.基本思路

2.算法描述

3.应用

二.深度优先搜索(DFS)

1.基本思路

2.算法描述

3.应用

三、代码实现

1.带权无向图的BFS与DFS算法的邻接矩阵结构实现

2.带权无向图的BFS与DFS算法的邻接表结构实现


(以下假设图G有V个结点E条边)

        图的遍历等价于寻找每个顶点的邻接点的过程,BFS与DFS在思路上仅仅是遍历策略上的区别,本质都是上述过程。

        一个图无论是有向图还是无向图,都有可能存在回路,这使得遍历操作必须防止重复访问某一结点,设置一个visited[MAX_VEX_NUM]数组来标记某个结点是否访问过可以解决此问题。

        下面分别给出BFS与DFS的思想、类C伪码与N-S流程图描述。

一.广度优先搜索(BFS)

*该方法类似树的层序遍历方法,要借助一个辅助队列实现

1.基本思路

         1.从图的某个顶点V0出发,访问此结点之后,依次访问V0的所有未被访问过的邻接点,然后再分别从这些邻接点出发,广度优先遍历图,直到图中所有已被访问结点的邻接点都被访问到。

        2.若此时图中还有顶点未被访问到,则另选一个图中未被访问到的顶点作为新起点,重复上述过程,直到图中所有结点都被访问到。

2.算法描述

        类似层序遍历思路,树的层序遍历算法就是由BFS启发得来。

        为便于理解,先给出伪代码实现。

bool visited[V]; 
void BFS(Graph G,v){
    //辅助队列
    InitQueue(Q);
    visited[v] = true;
    viist(v);       //访问
    EnQueue(Q, v);
    while(!QueueEmpty(Q)){
        DeQueue(Q, u);
        for (w = FisrtAdjvex(G, u); w != 0; w=NextAdjvex(G,u,w)){        
            //w为当前出队元u的第一个邻接点
            if(!visited[w]){
                visited[w] = true;
                visit(w);
                EnQueue(Q, w);
            }
        }
    }
}
void BFSTraverse(Graph G){
    for (v = 0; v < G.vexnum; ++v){
        visited[v] = false;        //初始化辅助数组
    }
    for (v = 0; v < G.vexnum; ++v){
        if(!visited[v]){
            BSF(G, v);
        }
    }
}

3.应用

        查找连通分量

        查找一个连通分量中所有结点

        查找两个结点之间最短路径

        判断偶图

二.深度优先搜索(DFS)

*该方法类似树的先序遍历方法

1.基本思路

        1.从图的某一顶点V0出发,访问此顶点,然后依次从V0未被访问的邻接点出发,深度优先遍历图,直到图中所有与V0相邻的顶点都被访问到为止。

        2.若此时图中仍有结点未被访问到,则选择图中未被访问到的结点作为起点,重复上述过程,直到图中所有顶点均被访问到为止。

2.算法描述

        类先序遍历思想

        初始时,所有顶点均被标记为未被访问;

        DFS从图的顶点v开始,考虑从v到其他顶点的边:

                如果边关联的另一个顶点已经访问过,则返回当前顶点v;

                如果边关联的另一个顶点未被访问过,转到该顶点访问并继续搜索;

        持续上述过程直到结尾,开始回溯。当回溯返回到起始顶点时,算法终止。

        为便于理解,先给出类C伪代码实现。

bool visited[V];     //标记是否已访问过某结点
void DFS(Graph G,v){
    visited[v] = true;     //置为已访问状态
    visit(v);       //操作
    for (w = FirstAdjvex(G, v); w!=0;w=NextAdjvex(G,v,w)){      //w寻找v下一未被访问的邻接点
        if(!visited[w]){
            DFS(G, w);
        }
    }
}
void DFSTraverse(Graph G){
    for (v = 0; v < G.vexnum;++v){
        visited[v] = false;     //初始化辅助数组
    }
    for (v = 0; v < G.vexnum;++v){
        if(!visited[v]){        //当前节点未被访问 DFS
            DFS(G, v);
        }
    }
}

3.应用

        拓补排序

        查找连通分量

        查找图关节点

        查找强连通分量

        解决迷宫问题等

三、代码实现

1.带权有向图的BFS与DFS算法的邻接矩阵结构实现

/* ===预定义=== */
#define MAX_VEX_NUM 10          //图最大节点数
#define MAX_EDGE_NUM  ((MAX_VEX_NUM * (MAX_VEX_NUM - 1)) / 2)
#define INF 2147483647         //表示无穷

typedef int VertexType;            //顶点数据类型
typedef int EdgeType;               //边权值
bool visited[MAX_VEX_NUM];      //全局数组  负责BFS与DFS时的顶点访问标记

/* ===辅助队列=== */
//存储结构循环队列
typedef struct{
    VertexType data[MAX_VEX_NUM];         //字符型
    int front;          //队头
    int rear;           //队尾
} SqQueue;
//初始化
void Ini
  • 4
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值