图的适配器

什么是图
图是一个由点的集合和边的集合所构成的数据结构。
图分为有向图和无向图。其中无向图也可以理解为有向图,所以可以认为所有的图都是有向图。
比方说,有这么一张图。其中a指向bc,b指向c,c指向p。边是带方向的,所以这是一个有向图。
图的适配器_第1张图片
而无向图呢? a连b,b连c,c连a。完全可以理解为ab互相指向,bc互相指向,ca互相指向,所以无向图也可以理解为都是有向图。
图的适配器_第2张图片

而图的表达方式有很多,其中常见的有邻接表法,邻接矩阵法等等。图的算法不难,难的是图的数据结构的表达。
比如说,给定一个n * 3的二维数组,[1 , 3 , 5],[0 , 5 , 5 ],[2 , 6 , 5]其中[i][0]代表的是边的权重,[i][1],[i][2]代表的是边从哪到哪。给的是每条边的权重以及从哪到哪,根据每条边画出来的图是这样的。这也是一种图的表示。
图的适配器_第3张图片
甚至更可以用1维数组表示一张图,所以用不同的方式表达图,所用到的解法也不同,每一种coding都要练习,那是不是可以将结构进行统一?无论什么样的图,都转换成自己的结构,将抽象化的图通过代码变得具象化,面向对象编程的思想更多一些。

代码
通过代码将点进行转化,Node对象中封装了这个点的所有基本信息,点的值,连接到这个点上的边有多少,从这个点出去的边有多少。

/*
* 点的描述
* */
public class Node {
    //点本身value
    public int value;
    //入度(有多少个点的边直接指向该点)
    public int in;
    //出度(从自己出发,直接指向别人的)
    public int out;
    //从自己出发能找到的边
    public ArrayList<Edge> edges;
    //从自己出发能找到的点
    public ArrayList<Node> nexts;

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

边的描述信息,包含边的权重,从哪个点连接到哪个点。

/*
* 边的描述信息
* */
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;
    }
}

一个图是由多个点和边所组成,所以包含了所有的点信息和边的信息,其中HashMap是具体的点的值和封装的点的对象。

/*
* 图的描述,包含了所有的点和所有的边
* */
public class Graph {

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

    public Graph(){
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}

生成图代码
以图形式为二维数组为例,[i][0]位置是边的权重,[i][1],[i][2]是从哪个点连到哪个点。

public class GraphGenerator {

    public static Graph createGraph(int[][] matrix) {
        Graph graph = new Graph();

        for (int i = 0; i < matrix.length; i++) {
            int weight = matrix[i][0];
            int from = matrix[i][1];
            int to = matrix[i][2];

            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 edge = new Edge(weight,fromNode,toNode);

            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(edge);
            graph.edges.add(edge);
        }
        return graph;
    }
}

你可能感兴趣的:(算法,数据结构,java,算法,图)