数据结构与算法之图的邻接表与邻接矩阵

现实中的许许多多的事务都是网状结构也就是图结构。当你面临一个复杂的网状关系问题。也许你已经有了解决的方法,但是如何用编程实现呢。首先的问题就是如何将网状图程序化。若是不能清楚简单的描述这些关系,对你解决问题是十分大的阻碍。同时也说明了将图的关系程序化是学习图论的基础

我这里就介绍两种常用且简单的方法来描述下图

这里写图片描述

邻接矩阵法
邻接矩阵法,顾名思义就是利用矩阵来描述各个节点之间的关系。将上述的图利用矩阵法表示就是下图所示

这里写图片描述

若节点之间存在边(这里是双向边)则置1否则置0
这样的话就可以将图的关系描述清楚

看了上述介绍,大家肯定了解邻接矩阵法的原理。下面我将使用Java来实现
水平有限 若有错误 欢迎指正


/*
 * 矩阵法 算法简述 创建矩阵,若节点之间存在边则置一否则置零 适用于稠密图
 */
public class GraphByMatrix {
    // 顶点列表中的顶点数量
    private Integer verticesCounts;
    // 关系矩阵
    boolean matrix[][];

    // 初始化 顶点数量
    public GraphByMatrix(int vertexCount) {
        matrix = new boolean[vertexCount][vertexCount];
        this.verticesCounts = vertexCount;
    }

    // 添加边
    public void addEdge(int i, int j) {
        // 判断添加的边是否合理(不能超出矩阵边界)
        if (i >= 0 && j >= 0 && i < verticesCounts && j < verticesCounts && i != j) {
            // 无向边界
            matrix[i][j] = true;
            matrix[j][i] = true;
        }
    }

    // 删除边
    public void removeEdge(int i, int j) {
        // 判断添加的边是否合理(不能超出矩阵边界)
        if (i >= 0 && j >= 0 && i < verticesCounts && j < verticesCounts && i != j) {
            // 无向边界
            matrix[i][j] = false;
            matrix[j][i] = false;
        }
    }

    // 是否存在边
    public boolean isEdge(int i, int j) {
        // 判断添加的边是否合理(不能超出矩阵边界)
        if (i >= 0 && j >= 0 && i < verticesCounts && j < verticesCounts && i != j) {
            return matrix[i][j];
        }
        return false;
    }
}

邻接表法

邻接表法的原理是利用链表数组来描述图的关系。链表数据方法的优势是数据紧凑,不像矩阵法,如果遇到稀疏表 矩阵法会浪费大量空间,而邻接表不会。
下面的图片将会描述邻接表的实现

这里写图片描述

下面用代码实现


/*
 * 若图节点多且关系稀疏 使用矩阵十分浪费空间 所以使用邻接图是十分有效的
 */
public class GraphByAdjoin<T> {
    private List<Integer> vertices;
    List<LinkedList<Node>> list;
    private int maxCount;

    // 初始化
    public GraphByAdjoin(int maxCount) {
        this.maxCount = maxCount;
        // 创建链表数组
        list = new ArrayList<LinkedList<Node>>(maxCount);
        // 初始化顶点列表
        vertices = new ArrayList<>(maxCount);
        // 初始化每个链表
        for (int i = 0; i < maxCount; i++) {
            // 顶点编号
            vertices.add(i);
            list.add(new LinkedList<Node>());
        }
    }

    // 添加边
    public void addEdge(int i, int j) {
        // 判断 i j的合法性
        if (i >= 0 && i < maxCount && j >= 0 && j < maxCount && i != j) {
            // 创建边
            list.get(i).add(new Node(j));
            list.get(j).add(new Node(i));
        }
    }
}

// 链表节点类
class Node {
    // 顶点编号
    int i;
    Node next;
    public Node(int i) {
        this.i = i;
    }
}

到此图的表示方法介绍到此结束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章