20162328蔡文琛 week10 大二

20162328 2017-2018-1 《程序設計與數據結構》第十週學習總結算法

教材學習內容總結

理解圖與有向圖、無向圖
理解帶權圖
會應用帶權圖
理解圖的廣度優先遍歷和深度優先遍歷
掌握最小生成樹算法
掌握圖的實現數組

有向圖,無向圖

若是給圖的每條邊規定一個方向,那麼獲得的圖稱爲有向圖,其邊也稱爲有向邊。在有向圖中,與一個節點相關聯的邊有出邊和入邊之分,而與一個有向邊關聯的兩個點也有始點和終點之分。相反,邊沒有方向的圖稱爲無向圖。

數據結構

帶權圖

在處理有關圖的實際問題時,每每有值的存在,好比千米數,運費,城市,人口數以及電話部數等。通常這個值成爲權值,帶權值的圖稱爲帶權圖或賦權圖。也稱爲網。學習

最小生成樹算法

public class WeightedGraph {
    private final int MAX_VERTS = 20; //最大頂點數
    private final int INFINITY = 100000; //最遠距離...表示沒法達到
    private Vertex[] vertexArray; //存儲頂點的數組
    private int adjMat[][]; //存儲頂點之間的邊界
    private int nVerts; //頂點數量
    private int currentVert; //當前頂點索引
    private PriorityQ thePQ; //存儲邊的優先級隊列
    private int nTree; //最小生成樹中的頂點數量

    public WeightedGraph() {
        vertexArray = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        for(int i = 0; i < MAX_VERTS; i++) {
            for(int j = 0; j < MAX_VERTS; j++) {
                adjMat[i][j] = INFINITY; //初始化全部邊界無窮遠
            }
        }
        thePQ = new PriorityQ();
    }

    public void addVertex(char lab) { //添加頂點
        vertexArray[nVerts++] = new Vertex(lab);
    }

    public void addEdge(int start, int end, int weight) {//添加帶權邊
        adjMat[start][end] = weight;
        adjMat[end][start] = weight;
    }

    public void displayVertex(int v) {
        System.out.print(vertexArray[v].label);
    }

    /*
     * 帶權圖的最小生成樹,要選擇一條最優的路徑
     */
    public void MinSpanningTree() {
        currentVert = 0; //從0開始
        while(nTree < nVerts-1) { //當不是全部節點都在最小生成樹中時
            //isInTree是上一節Vertex類中新添加的成員變量 private boolean isInTree;
               //表示有沒有加入到樹中,初始化爲false
vertexArray[currentVert].isInTree = true; //將當前頂點加到樹中
            nTree++;

            //往PQ中插入與當前頂點相鄰的一些邊界
            for(int i = 0; i < nVerts; i++) {
                if(i == currentVert) //若是是本頂點,跳出
                    continue;
                if(vertexArray[i].isInTree) //若是頂點i已經在樹中,跳出
                    continue;
                int distance = adjMat[currentVert][i]; //計算當前頂點到i頂點的距離
                if(distance == INFINITY) 
                    continue; //若是當前頂點與i頂點無窮遠,跳出
                putInPQ(i, distance); //將i節點加入PQ中
            }

            if(thePQ.size() == 0) { //若是PQ爲空,表示圖不鏈接
                System.out.println("Graph not connected!");
                return;
            }

            Edge theEdge = thePQ.removeMin();
            int sourceVert = theEdge.srcVert;
            currentVert = theEdge.destVert;

            System.out.print(vertexArray[sourceVert].label);//這裏就是一步步打印最小生成樹的路徑
            System.out.print(vertexArray[currentVert].label);
            System.out.print(" ");
        }
    }
    //這個方法是將一個Edge放入優先級隊列,保證隊列中每一個Edge的des頂點是不一樣的。
    private void putInPQ(int newVert, int newDist) {
        int queueIndex = thePQ.find(newVert);//判斷PQ中是否已經有到相同目的頂點的邊界
        if(queueIndex != -1) { //若是有則與當前頂點到目的頂點的距離做比較,保留短的那個
            Edge tempEdge = thePQ.peekN(queueIndex);//get edge
            int oldDist = tempEdge.distance;
            if(oldDist > newDist) { //若是新的邊界更短
                thePQ.removeN(queueIndex); //刪除舊邊界
                Edge theEdge = new Edge(currentVert, newVert, newDist);
                thePQ.insert(theEdge);
            }
        }
        else { //若是PQ中沒有到相同目的頂點的邊界
            Edge theEdge = new Edge(currentVert, newVert, newDist);
            thePQ.insert(theEdge);//直接添加到PQ
        }
    }
}
相關文章
相關標籤/搜索