图的深度优先遍历和广度优先遍历(java)

265 篇文章 2 订阅
33 篇文章 0 订阅

图的数据结构(自定义的点加线实现的图结构)

利用点线的组合来实现图的结构,优势就是结构清晰,容易理解,表达的数据项多。便于很多图的算法。
具体实现可以查看上期连接
自定义图结构

自定义图结构的代码

/**
 * 线
 */
public class Edge {

    /**
     * 线的权重
     */
    private int weight;
    /**
     * 这个是点的结构 先理解为头节点
     */
    private Node from;
    /**
     * 理解为尾节点或者出节点。
     */
    private Node to;


    public Edge(int weight, Node from, Node to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }
}

/**
 * 点的数据结构
 */
public class Node {
    public int value;
    //出度
    public int out;
    //入度
    public int in;
    //边的集合(这个点的所有线段集合)
    public ArrayList<Edge> edges;
    //点的集合(从这个点往下能走到的点)
    public ArrayList<Node> nests;

    public Node(int value) {
        this.value = value;
        in = 0;
        out = 0;
        edges = new ArrayList<>();
        nests = new ArrayList<>();
    }
}


/**
 * 图结构
 */
public class Graph {

    public HashMap<Integer,Node> nodes;
    public List<Edge> edges;

    public Graph() {
        this.nodes = new HashMap();
        this.edges = new ArrayList();
    }

}

广度优先遍历

思路:
类似二叉树的按层遍历。在图中遍历时,我们把当前节点放进队列中,然后弹出后,判断有没有直接子节点,有的话继续压入队列中。
和二叉树遍历的区别是:图中有可能有回路,会跑到重复节点,所以需要增加一个新的HashSet表进行去重。

代码实现

  /**
     * 宽度优先遍历
     * @param start
     */
    public static void bfs(Node start){
        if (start == null){
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        //记录已经遍历过的节点
        HashSet<Node> set = new HashSet<>();
        queue.add(start);
        set.add(start);
        while (!queue.isEmpty()){
            Node poll = queue.poll();
            System.out.println(poll.value);
            //去重
            for (Node cur : poll.nests){
                if (!set.contains(cur)){
                    queue.add(cur);
                    set.add(cur);
                }
            }
        }
    }

深度优先遍历

深度优先遍历有点类似于前序遍历,是从图的某一顶点开始遍历,被访问过的顶点就做上已访问的记号,接着遍历此顶点的所有相邻且未访问过的顶点中的任意一个顶点,并做上已访问的记号,再以该点为新的起点继续进行深度优先遍历

在这里插入图片描述

 /**
     * 深度优先遍历
     * @param start
     */
    public static void dfs(Node start){
        if (start == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        //辅助 为了帮助去重
        HashSet<Node> set = new HashSet<>();
        stack.push(start);
        set.add(start);
        System.out.println(start.value);
        while (!stack.isEmpty()){
            Node cur = stack.pop();
            for (Node next : cur.nests){
                if (!set.contains(next)){
                    //发现下面还有节点,就重新压入 是的stack 里保持有一条完整的链。
                    stack.push(cur);
                    stack.push(next);
                    System.out.println(next.value);
                    set.add(next);
                    break;
                }
            }
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值