數據結構與算法之圖的鄰接表與鄰接矩陣

現實中的許許多多的事務都是網狀結構也就是圖結構。當你面臨一個複雜的網狀關係問題。也許你已經有了解決的方法,但是如何用編程實現呢。首先的問題就是如何將網狀圖程序化。若是不能清楚簡單的描述這些關係,對你解決問題是十分大的阻礙。同時也說明了將圖的關係程序化是學習圖論的基礎

我這裏就介紹兩種常用且簡單的方法來描述下圖

這裏寫圖片描述

鄰接矩陣法
鄰接矩陣法,顧名思義就是利用矩陣來描述各個節點之間的關係。將上述的圖利用矩陣法表示就是下圖所示

這裏寫圖片描述

若節點之間存在邊(這裏是雙向邊)則置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;
    }
}

到此圖的表示方法介紹到此結束

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