IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法和数据结构-图 -> 正文阅读

[数据结构与算法]算法和数据结构-图

1. 图的实现

Graph.java

public class Graph {
    public HashMap<Integer, Node> nodes;  // 图中节点符号和实际节点的对应关系,节点可以由0、1、2指代,也可能由A、B、C指代
    public HashSet<Edge> edges;  // 图中所有的边
    public Graph() {
        this.nodes = new HashMap<>();
        this.edges = new HashSet<>();
    }
}

Edge.java

public class Edge {
    public int weight;  // 边的权重
    public Node from;  // 边的出发点
    public Node to;  //边的结束点
	public Edge(int weight, Node from, Node to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }
}

Node.java


```java
public class Node {
    public int value; // 图中节点的代表符号,如果用A、B等表示节点,这里需要改为String类型
    public int in;  // 入度
    public int out; // 出度
    public ArrayList<Node> nexts; // 对于无向图,存储的是邻接点;对于有向图,存储的是出去的边连接的点
    public ArrayList<Edge> edges; // 对于无向图,存储的是连接在该点上的边;对于有向图,存储的是出去的边
    public Node(int value) {
        this.value = value;
        this.in = 0;
        this.out = 0;
        this.nexts = new ArrayList<>();
        this.edges = new ArrayList<>();
    }
}
  • 创建了Graph类以及Graph中的Edge类和Node类后,可能会遇到许多表示图的方式,但是包含的信息全部都在Graph类中。不管表达方式怎么变,将这些方式中的信息填入到创建的Graph类中,就可在后续写图算法时更加方便。
  • 以其中一种图表达方式为例进行转换:N*3的矩阵,每一个数组表示[from节点的符号值,to节点的符号值,连接两个点的边的权重]
public static Graph createGraph(Integer[][] matrix) {
        Graph graph = new Graph();
        for (int i = 0; i < matrix.length; i++) {
            Integer from = matrix[i][0];
            Integer to = matrix[i][1];
            Integer weight = matrix[i][2];
            // 如果graph中没有存储该点
            if (!graph.nodes.containsKey(from)) {
                graph.nodes.put(from, new Node(from));
            }
            if (!graph.nodes.containsKey(to)) {
                graph.nodes.put(to, new Node(to));
            }
		Node fromNode = graph.nodes.get(from);
        Node toNode = graph.nodes.get(to);
            // 根据提供的信息构建边
            Edge newEdge = new Edge(weight, fromNode, toNode);
            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(newEdge);
            graph.edges.add(newEdge);
        }
	 return graph;
}

2. 图的宽度优先遍历

public class BFS {
    public static void bfs(Node node){
        if (node == null){
            return;
        }

        Queue<Node> queue = new LinkedList<>();
        // 假设在无向图中A点邻接点有B、C,将B、C放入队列后弹出A。继续往下遍历B点,由于A是B的邻接点,所以会将A再次放入队列中,导致无法跳出循环
        // 需要使用Set结构去避免上述情况
        HashSet<Node> map = new HashSet<>();

        queue.add(node);
        map.add(node);

        while (!queue.isEmpty()){
            Node cur = queue.poll();
            System.out.println(cur.value);
            for (Node next : cur.nexts){
                // 避免重复放入
                if (!map.contains(next)){
                    map.add(next);
                    queue.add(next);
                }
            }
        }

    }
}

3. 图的深度优先遍历

public class DFS {
    public static void dfs(Node node) {
        if (node == null) {
            return;
        }
        // 栈保存的是bfs的路径
        Stack<Node> stack = new Stack<>();
        HashSet<Node> map = new HashSet<>();

        stack.add(node);
        map.add(node);

        System.out.println(node);

        while (!stack.isEmpty()) {
            Node cur = stack.pop();
            for (Node next : cur.nexts) {
                if (!map.contains(next)) {
                    // 为了保证栈储存的是bfs的路径,每一个路径上的点需要重新压入栈中
                    stack.push(cur);
                    stack.push(next);
                    map.add(next);
                    System.out.println(next.value);
                    // 找到一个当前节点没有遍历过的邻接点后,直接break去再次执行while循环
                    // 假设当前节点为A,A的邻接点有B和C,下一次的while循环就是从B开始处理,不再管A的另一个邻接点C
                    break;
                }
            }
        }
    }
}

4. 拓扑排序

 拓扑排序:以项目中的依赖包为例,假设B包依赖A包,C包依赖A包和B包,D包依赖B包和C包,如何确定包的编译顺序?
 下图为一个有向无环图
          A --> B --> C --> D
          |     |     ↑     ↑
          ------|------     |
                -------------
      1. 找到入度为0的点,图中为A
      2.A点和A相关的边全部移除,A就称为第一个编译的包
      3. 再次重复1-2直到所有节点排好序
public class TopologySort {
    public static List<Node> sortedTopology(Graph graph){
        // key为node节点,value为该节点当前的入度
        HashMap<Node, Integer> inMap = new HashMap<>();

        // 存储入度为0的点
        Queue<Node> zeroInqueue = new LinkedList<>();

        // 1. 构建inMap并存储第一个入度为0的点
        for (Node node : graph.nodes.values()){
            inMap.put(node, node.in);
            if (node.in == 0){
                zeroInqueue.add(node);
            }
        }

        // 存储拓扑排序的结果
        List<Node> result = new ArrayList<>();

        while (!zeroInqueue.isEmpty()){
            Node cur = zeroInqueue.poll();
            result.add(cur);
            // 2. 将和入度为0点相关的边全部移除
            for (Node next : cur.nexts){
                inMap.put(next, inMap.get(next)-1);
                if (inMap.get(next) == 0){
                    zeroInqueue.add(next);
                }
            }
        }

        return result;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:10:13  更:2022-01-28 12:12:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 19:59:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码