遍历图

作为开发人员,我们经常处理列表,数组和值序列。 但是,您是否曾经不得不处理与其他数据相关的相关数据? 这也称为图形。

These days I had to deal with it. It was scary at first.
But after reading this great article from Kumar Chandrakant, it became understandable and I felt capable of doing that.

当然,还有很多东西要学习,但是我将向您展示基础知识,因此您有一个起点来加深您的研究。

一种 graph is a collection of Vertices (also called Nodes or Points) and Edges (also called Links or Lines), where an edge is the connections between two vertices.
In a social network, each person is a vertex, and each connection between them is the edge.
Kumar's diagram

Kumar's diagram

In a map, the streets are the edges and their intersections are the vertices.

Route on map
M&M's time!😋

使用库马尔的图作为示例,让我们编写代码。 第一步是创建一个顶点类:

public class Vertex {
    String name;
    Vertex(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null)
            return false;

        if (this == o)
            return true;

        return ((o instanceof Vertex) && (((Vertex) o).getName() == this.name));
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return name;
    }
}

基本上,顶点只有“名称”属性。 但是,由于我们将使用Java集合,因此必须重写等于,hashCode,and toString方法。

现在,该图形类:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Graph {
    private Map<Vertex, List<Vertex>> adjVertices;

    public Graph() {
        this.adjVertices = new HashMap<Vertex, List<Vertex>>();
    }

    void addVertex(String name) {
        adjVertices.putIfAbsent(new Vertex(name), new ArrayList<>());
    }

    void addEdge(String name1, String name2) {
        Vertex v1 = new Vertex(name1);
        Vertex v2 = new Vertex(name2);
        adjVertices.get(v1).add(v2);
        adjVertices.get(v2).add(v1);
    }

    List<Vertex> getAdjVertices(String name) {
        return adjVertices.get(new Vertex(name));
    }

    String printGraph() {
        StringBuffer sb = new StringBuffer();
        for(Vertex v : adjVertices.keySet()) {
            sb.append(v);
            sb.append(adjVertices.get(v));
            sb.append("\n");
        }
        return sb.toString();
    }
}

我们正在使用地图创建一个邻接表。 该列表将包含每个顶点的所有关系。 添加边时,我们在相关顶点的列表上添加一个顶点。 To represent the graph, we print the 邻接表, creating a string that starts with each vertex and shows the related list in front of it.

然后,我们将创建一个ves类,它将包含遍历图的方法。 两种方法都会收到图形还有一个根(这将是我们的起点)作为参数。 There are several ways for traversing a 图形, but in this article, we will only show the two most commonly used。 They are known as 深度优先遍历(DFT)和广度优先遍历(BFT)。 它们之间的主要区别在于DFT每次拜访儿童连接直到结束,然后再开始访问兄弟姐妹。 的BFT, on the other hand,每次拜访兄弟首先先拜访他们的儿童ren。

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;

public class Traversal {
    static Set<String> depthFirstTraversal(Graph graph, String root) {
        Set<String> visited = new LinkedHashSet<String>();
        Stack<String> stack = new Stack<String>();
        stack.push(root);
        while(!stack.isEmpty()) {
            String vertex = stack.pop();
            if (!visited.contains(vertex)) {
                visited.add(vertex);
                for (Vertex v : graph.getAdjVertices(vertex)) {
                    stack.push(v.name);
                }
            }
        }
        return visited;
    }

    static Set<String> breadthFirstTraversal(Graph graph, String root) {
        Set<String> visited = new LinkedHashSet<String>();
        Queue<String> queue = new LinkedList<String>();
        queue.add(root);
        visited.add(root);
        while (!queue.isEmpty()) {
            String vertex = queue.poll();
            for (Vertex v : graph.getAdjVertices(vertex)) {
                if (!visited.contains(v.name)) {
                    visited.add(v.name);
                    queue.add(v.name);
                }
            }
        }
        return visited;
    }
}

请注意DFT我们使用堆存储将要遍历的顶点,这使我们在每个顶点都更深入。 在里面BFT,我们使用队列存储顶点,这首先使我们成为邻居。

最后,我们在main方法中创建一个图,定义它的顶点和边,然后打印邻接表并使用两种遍历遍历它。

public class TraverseGraph {
    public static void main(String[] args) {

        Graph graph = new Graph();
        graph.addVertex("Bob");
        graph.addVertex("Alice");
        graph.addVertex("Mark");
        graph.addVertex("Rob");
        graph.addVertex("Maria");
        graph.addEdge("Bob", "Alice");
        graph.addEdge("Bob", "Rob");
        graph.addEdge("Alice", "Mark");
        graph.addEdge("Rob", "Mark");
        graph.addEdge("Alice", "Maria");
        graph.addEdge("Rob", "Maria");

        System.out.println(graph.printGraph());     

        System.out.println(Traversal.depthFirstTraversal(graph, "Bob"));

        System.out.println(Traversal.breadthFirstTraversal(graph, "Bob"));  

    }
}

结果将是以下内容:

Bob[Alice, Rob]
Rob[Bob, Mark, Maria]
Mark[Alice, Rob]
Alice[Bob, Mark, Maria]
Maria[Alice, Rob]

[Bob, Rob, Maria, Alice, Mark]
[Bob, Alice, Rob, Mark, Maria]

我希望本文能阐明图表。 Leave your impressions or doubts。

Sources:
[1]https://www.baeldung.com/java-graphs
[2]https://dev.to/amberjones/intro-to-graph-data-structures-abk
[3]https://dev.to/vaidehijoshi/going-broad-in-a-graph-bfs-traversal
[4]https://dev.to/jjb/part-9-learning-graphs-4859

from: https://dev.to//vmacarios/traversing-graphs-4ie1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值