数据结构与算法之图的深度遍历<十四>

学习图的遍历之前得知道图的表示方法
可以参考
图的表示方法

进入正题
什么是图的深度遍历算法
所谓深度遍历 就是一口气一条路走到底,再回溯重复便可达到遍历效果
一组图片来说明这个问题
深度遍历这个图

图

第一步
这里写图片描述

第二步
这里写图片描述

依次遍历直到到最底部

这里写图片描述

到达底部后 回溯重复 也就是回溯到C
然后,C开始访问未访问的边,也是访问到底部

这里写图片描述

F回溯到E E开始访问未访问的边

这里写图片描述

D回溯 到 E E开始访问未访问的边

这里写图片描述

到此所有的节点已经访问完成 但是程序并未停止直到回溯至A点(递归的特性)

上面的图片非常清楚的描述了深度遍历的过程
接下来我将用Java实现这个算法
水平有限 若有错误 欢迎指正

//这里使用的是邻接矩阵方法
public class DFS {
    GraphByMatrix graphByMatrix = new GraphByMatrix(10);
    Stack<Node> stack;
    List<Node> list;

    class Node {
        // 节点数据
        String str;
        boolean visited;
        // 该节点对应在关系矩阵中的编号
        int numner;

        public Node(String str, int num) {
            this.str = str;
            this.numner = num;
        }
    }

    public DFS() {
        stack = new Stack<>();
        list = new ArrayList<Node>();
        for (int i = 0; i < 8; i++) {
            // 节点内容分别为A-H 对应编号0-7
            list.add(new Node(new String(Character.toChars('A' + i)), i));
        }
    }

    public void Dfs() {
        // 被访问过
        list.get(7).visited = true;
        System.out.print(list.get(7).str + "  ");
        // 被访问过后压入栈
        stack.push(list.get(7));
        // 栈不为空则没有遍历完全
        while (!stack.isEmpty()) {
            // 返回栈顶元素
            Node peek = stack.peek();
            int nextVertex = getNextVertex(peek);
            // 没找到 证明所有边都已经遍历
            if (nextVertex == -1) {
                // 删除这个顶点
                stack.pop();
                // 找到了 将这个点作为下一次的顶点
            } else {
                list.get(nextVertex).visited = true;
                System.out.print(list.get(nextVertex).str + "  ");
                stack.push(list.get(nextVertex));
            }
        }
    }

    // 递归
    public void DFs(int index, List<Node> list) {
        //访问到底部或者该节点没有未访问的边
        if (index == -1)
            return;
        Node node = list.get(index);
        node.visited = true;
        System.out.print(node.str + " ");
        while (getNextVertex(node) != -1)
            DFs(getNextVertex(node), list);
    }
    //获取与Node 相连的未访问的边
    public int getNextVertex(Node peek) {
        boolean[][] matrix = graphByMatrix.matrix;
        for (int i = 0; i < matrix.length; i++) {
            // 查找顶点没有访问过的节点
            if (matrix[peek.numner][i] == true && list.get(i).visited == false) {
                return i;
            }
        }
        return -1;
    }

    //建立图 用来测试的
    public void bulid() {
        //描述关系 这里是双向边 所以 A B 相连后不需要 B A相连会自动连上
        //A B 相连
        graphByMatrix.addEdge(0, 1);
        //B C 相连 
        graphByMatrix.addEdge(1, 2);
        //B D 相连
        graphByMatrix.addEdge(1, 3);
        //C G 相连
        graphByMatrix.addEdge(2, 6);
        // C E 相连
        graphByMatrix.addEdge(2, 4);
        // D E 相连 
        graphByMatrix.addEdge(3, 4);
        // E F 相连
        graphByMatrix.addEdge(4, 5);
        // E H 相连
        graphByMatrix.addEdge(4, 7);
    }
}

测试代码

    public static void main(String[] args) {
        DFS dfs = new DFS();
        dfs.bulid();
        dfs.Dfs(0);
    }

结果
A  E  C  B  D  G  F  H 

发现和上面推理的顺序不一样原因在于矩阵法的构建
节点会找矩阵中离他近的边 

图片只是描述深度遍历的过程,当一个节点有多条未访问的边,选择的不同,会导致结果的不一样。

到此深度遍历差不多结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值