图结构-图的数据表示法(java)

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

常见的图的数据表示法

1.邻接矩阵表示法:用二维数组存储图的信息,数组中的对角线为0,表示不存在顶点到自身的边。若两个顶点之间有一条弧,则邻接矩阵中对应的元素为1,否则为0。该方法在存储稀疏图时效率较高。
2.关联矩阵表示法:与邻接矩阵类似,但在关联矩阵中,每个顶点的每条边对应的元素为1或-1,表示该边的终点或起点。该方法在存储密集图时效率较高
3.邻接表表示法:用链表存储图的信息,每个顶点对应一个链表,链表中存储了与该顶点相邻的所有顶点。该方法在查找顶点相邻的边时效率较高。
4.压缩邻接表表示法:将邻接表表示法中的每个顶点的链表进行压缩,即将相邻的顶点所在的边存储在链表的元素中。该方法在存储稠密图时效率较高。

自定义一种数据结构来表示图。

思路:图有点和线组成,线上又可以有权重,那我们先把线定义出来,在定义出点,最后把线和点组成一张图,这种结构会比较清晰,比邻接矩阵法之类的更好理解。

1.先定义出线段

/**
 * 线
 */
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;
    }
}

2.定义出点信息

/**
 * 点的数据结构
 */
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<>();
    }
}

3.把点和线组装起来成一张图

/**
 * 图结构
 */
public class Graph {
 
    public HashMap<Integer,Node> nodes;
    public List<Edge> edges;

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

}

将一个线段集合转成我们自定义的图

线段集合的数据样式:
{[2,3,5], [1,2,5], [3,4,5]}
第一个数字代表线段的权重 ,第二个数字代表线段的头节点,第三个数字代表尾节点。

/**
 * 二维数组转换成图
 * [1,2,3]
 * 1 weight
 * 2 from
 * 3 to.
 */
public class GraphGenerate {

    /**
     * 二维数组转成图结构。
     * @param matrix
     * @return
     */
    public Graph createGraph(int[][] matrix){
        if (matrix == null || matrix.length == 0){
            return null;
        }
        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.nests.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(edge);
            graph.edges.add(edge);

        }
        return graph;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值