java數據結構之圖

圖:

        一種多對多的數據結構,可以使用鄰接矩陣來存儲數據(鄰接矩陣:假如有M個點,則創建 M * M 的鄰接矩陣,【0,1】點表示0到1的點,如果其值不爲0,則表示0到1的權值),如果邊比較少,矩陣稀疏此方式比較浪費內存;這時候可以使用鄰接表來存儲數據(鄰接表: 創建一個長度爲M的數組a[M], 其中a[0]表示第0個節點,其值爲一個鏈表,鏈表立裏保存的是與第0個節點相鏈接的點),鄰接表相對省內存,但是操作沒有鄰接矩陣方便。一般途中用v表示點,u表示邊;圖可以分爲有向圖和無向圖,無向圖——A可以到B,則默認的B可以到A,點到點之間沒有方向;有向圖——A可以到B,但是B不一定可以到A,點到點之間是有方向的。加權圖——點到點之間的距離不一樣,它們之間不同的距離用不同的權來表示,還可以稱爲網。

圖的廣度優先遍歷與深度優先遍歷:

public class MapDemo {
    private ArrayList<String> vertexList; //存儲頂點集合
    private int[][] edges; //
    private int numOfedges; //表示邊的數目
    //定義一個數組用來記錄某個頂點是否被訪問過
    private boolean[] isVisited;

    public static void main(String[] args) {
        //測試
        int n = 8;
//        String VertexVal[] = {"A", "B","C","D","E"} ;
        String VertexVal[] = {"1", "2","3","4","5","6","7","8"} ;
        //創建圖對象
        MapDemo mapDemo = new MapDemo(n);
        for (String val : VertexVal) {
            mapDemo.insertVertex(val);
        }
        //添加邊
        mapDemo.insertEdge(0,1,1);
        mapDemo.insertEdge(0,2,1);
        mapDemo.insertEdge(1,3,1);
        mapDemo.insertEdge(1,4,1);
        mapDemo.insertEdge(3,7,1);
        mapDemo.insertEdge(4,7,1);
        mapDemo.insertEdge(2,5,1);
        mapDemo.insertEdge(2,6,1);
        mapDemo.insertEdge(5,6,1);
        mapDemo.showMap();

        System.out.println("深度優先遍歷");
        mapDemo.dfs();

//        mapDemo.bfs();
    }

    //構造器
    public MapDemo(int n) {
        //初始化矩陣和vertexList
        edges = new int[n][n];
        vertexList = new ArrayList<>(n);
        numOfedges = 0;
        isVisited = new boolean[n];
    }

    //得到第一個鄰接節點的下標w
    public int getFirstNeighbor(int index) {
        for (int j = 0; j < vertexList.size(); j++) {
            if (edges[index][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    //根據前一個鄰接節點的下標,獲取下一個鄰接節點
    public int getNextNeighbor(int v1, int v2) {
        for (int j = v2+1; j < vertexList.size(); j++) {
            if (edges[v1][j] > 0) {
                return j;
            }
        }

        return -1;
    }

    //深度優先遍歷
    public void dfs(boolean[] isVisited, int i) {
        //訪問該節點
        System.out.print(getValueByIndex(i) + "->");
        isVisited[i] = true;

        int w = getFirstNeighbor(i);
        while (w != -1) {
            if (!isVisited[w]) {
                dfs(isVisited, w);
            }
            w = getNextNeighbor(i, w);
        }

    }
    //
    public void dfs() {
        //遍歷所有的節點
        for (int i = 0; i < getNumOfVertex(); i++) {
            if (!isVisited[i] ) {
                dfs(isVisited, i);
            }
        }
    }

    //廣度優先算法
    private void bfs() {
        int u; //表示隊列的頭結點對應的下標
        int w; //鄰接節點w
        int i = 0;
        //隊列
        LinkedList<Integer> queue = new LinkedList<>();
        queue.addLast(i);
        isVisited[i] = true;
        while (!queue.isEmpty()) {
            //取出隊列的頭
            Integer integer = queue.removeFirst();
            u = integer;
            w = getFirstNeighbor(u);
            while (w != -1) {
                if (!isVisited[w]) {
                    isVisited[w] = true;
                    queue.addLast(w);
                }
                w = getNextNeighbor(u, w);
            }

            System.out.print(getValueByIndex(u) + "=>");
        }

    }

    //返回節點的個數
    public int getNumOfVertex() {
        return vertexList.size();
    }

    //得到邊的數目
    public int getNumOfedges() {
        return numOfedges;
    }
    //返回i下標對應的數據: 0 -> A, 1 -> B, 2->C
    public String getValueByIndex(int i) {
        return vertexList.get(i);
    }

    //返回v1和v2的權值
    public int getWeight(int v1, int v2) {
        return edges[v1][v2];
    }

    //插入節點
    public void insertVertex(String vertex) {
        vertexList.add(vertex);
    }

    //顯示圖對應的矩陣
    public void showMap() {
        for (int i = 0; i < edges.length; i++) {
            System.err.println(Arrays.toString(edges[i]));
        }
    }

    //添加邊
    /**
     *
     * @param v1 表示點的下標,即第幾個頂點
     * @param v2 表示點的下標,
     * @param weight 路徑上的權值
     */
    public void insertEdge(int v1, int v2, int weight) {
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfedges++;
    }

}

 

發佈了52 篇原創文章 · 獲贊 4 · 訪問量 9334
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章