经典算法与数据结构(4)—— 图的遍历与常见算法实现(最小路径+最小生成树+拓扑排序)

本文详述了图的遍历方法,包括广度优先遍历(BFS)和深度优先遍历(DFS),以及如何实现拓扑排序、Kruskal算法和Prim算法。这些算法在图的最小路径和最小生成树问题中起关键作用。通过实例解释了每个算法的工作原理,并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

前言

上一篇博客里讲了图结构的代码实现,本篇就记录一下,如何利用上一篇介绍的图结构,进行图的遍历(BFS + DFS)以及实现图相关的常见算法,包括Prim算法、Kruskal算法、Dijkstra算法以及拓扑排序。

关于图的这些算法,一直以来只是停留在了解算法思想的程度,还没有动手实现过。全部实现一遍过后,会发现代码量并不大,思想也都比较朴素,没有特别精巧难理解的那种。即便如此,亲手写一遍也还是很有必要的,比如K算法的实现,我还真一时想不到是用并查集实现的😮😮😮。

广度优先遍历(BFS)

  • 定义:由指定结点begin作为开始结点,由近及远遍历,具体的含义就是,先遍历离begin距离短的,再遍历距离远的,相同距离的结点顺序不做要求。

注意不管是BFS还是DFS都需要一个Set来维护已经遍历过的结点防止重复遍历,因为可能某一个结点p跟begin的距离为1,但是遍历到距离为3的某个结点时,这个结点的nexts结点集合包含p,这个时候不应该重复遍历p。

下面看代码实现,核心思想是利用队列结构,跟树的层次遍历是一个道理,区别在于需要利用set进行一个去重:


public class BFS {
   
    public static void bfs(Graph graph, Node node){
   
        
        Queue<Node> que = new LinkedList<>();
        HashSet<Node> set = new HashSet<>();

        que.offer(node);
        
        while (!que.isEmpty()){
   
            Node tmp = que.poll();
            System.out.println(tmp.value);
            for (Node n : tmp.nexts) {
   
                if (!set.contains(n)) {
   
                    que.offer(n);
                    set.add(n);
                }
            }
        }
    }

    
    public static void main(String[] args) {
   
        int[][] matrix = {
   {
   0,1,2}, {
   0,1,3}, {
   0,1,4}, {
   0,2,3}, {
   0,2,7}, {
   0,7,3}, {
   0,3,5}, {
   0,4,6}};
        Graph graph = CreateGraph.createGraph(matrix);
        Node begin = graph.nodes.get(1);
        BFS.bfs(graph, begin);
    }
}
// 输出结果:1,2,3,4,7,5,6

深度优先遍历(DFS)

  • 定义:由给定结点开始,一直往下遍历,直到到头了再回溯走另一条路径。

与BFS相比,DFS的核心思想是利用栈结构,类似树的非递归遍历(这个在左神的课上已经看过了,还没写博客,下次补上。比起树的递归遍历,还是要稍复杂一些的)。

下面看DFS代码实现,大体思路是:由begin结点开始,先poll,再遍历其nexts数组(即指向的邻居结点),一旦遇到一个set中还没有的,记为p,就把begin和p一起加入栈中,打印p,再由p作为begin开始重复上述过程,看代码吧:


public class DFS {
   
    public static void 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值