20182305 2019-2020-1 《數據結構與面向對象程序設計》實驗九報告

20182305 2019-2020-1 《數據結構與面向對象程序設計》實驗八報告

課程:《程序設計與數據結構》
班級: 1823
姓名: 孫銘澤
學號:20182305 
實驗教師:王志強
實驗日期:2019年12月2日
必修/選修: 必修

1.實驗內容

  • (1) 初始化:根據屏幕提示(例如:輸入1爲無向圖,輸入2爲有向圖)初始化無向圖和有向圖(可用鄰接矩陣,也可用鄰接表),圖須要本身定義(頂點個數、邊個數,建議先在草稿紙上畫出圖,而後再輸入頂點和邊數)(2分)算法

  • (2) 圖的遍歷:完成有向圖和無向圖的遍歷(深度和廣度優先遍歷)(4分)數組

  • (3) 完成有向圖的拓撲排序,並輸出拓撲排序序列或者輸出該圖存在環(3分)數據結構

  • (4) 完成無向圖的最小生成樹(Prim算法或Kruscal算法都可),並輸出(3分)設計

  • (5) 完成有向圖的單源最短路徑求解(迪傑斯特拉算法)(3分)指針

2. 實驗過程及結果

  • 按照實驗要求進行每一步的操做。
    初始化圖
public void create()
    {
        System.out.print("請輸入結點數:");
        vexnum = input.nextInt();
        vexs = new char[vexnum]; // vexnum長度的頂點數組
        isVisited = new int[vexnum];
        System.out.print("請輸入邊數:");
        arcnum = input.nextInt();
        adjMatrix = new int[vexnum][vexnum];
        //構建頂點數組
        System.out.println("請依次輸入頂點:");

        for(int i=0;i<vexnum;i++)
        {
            vexs[i] = input.next().charAt(0);
        }

        //初始化鄰接矩陣
        for(int i=0;i<vexnum;i++)
            for(int j=0;j<vexnum;j++)
                adjMatrix[i][j]=0;

        int i = 0;
        int vexA, vexB;
        while (i < arcnum) {
            System.out.println("請輸入相鏈接的結點");
            vexA = input.nextInt();
            while (vexA < 1 || vexA > vexnum)
            {
                System.out.println("範圍不符合,請從新輸入:");
                vexA = input.nextInt();
            }
            vexB = input.nextInt();
            while (vexB < 1 || vexB > vexnum)
            {
                System.out.println("範圍不符合,請從新輸入:");
                vexB = input.nextInt();
            }
            adjMatrix[vexA - 1][vexB - 1] = 1;
            adjMatrix[vexB - 1][vexA - 1] = 1;

            if (i == arcnum - 1)
            {
                System.out.println("Ending!");
            }
            else
            {
                System.out.println("Continue!");
            }
            i++;
        }
    }
![](https://img2018.cnblogs.com/blog/1780041/201912/1780041-20191208152413735-451025846.png)

對圖進行遍歷操做code

public void DFS(int i)
    {
        isVisited[i]=1;
        System.out.print(vexs[i]);
        for(int j=0;j<vexnum;j++){
            if(adjMatrix[i][j]==1&&isVisited[j]==0)
            {
                System.out.print("—>");
                DFS(j);
            }
        }

    }
public void BFS()
    {
        char temp=(char)list.poll();
        int x=temp-'0'; // 轉換爲數字
        isVisited[x-1]=1;
        System.out.print(temp);
        List nerborpointlist=getCurrent(x-1);
        for(int i=0;i<nerborpointlist.size();i++){
            char j=(char)nerborpointlist.get(i);
            list.add(j);
            int k=j-'0';
            isVisited[k-1]=1;
        }
        if(!list.isEmpty()){
            System.out.print("—>");
            BFS();
        }
    }


prim算法:對象

public void prim( float[][] weight) {  //num爲頂點數,weight爲權
        float[] lowcost = new float[vexnum + 1];  //到新集合的最小權
        int[] closest = new int[vexnum + 1];  //表明與s集合相連的最小權邊的點

        boolean[] s = new boolean[vexnum + 1];  //s[i] == true表明i點在s集合中

        s[1] = true;  //將第一個點放入s集合

        for(int i = 2; i <= vexnum; i++) {  //初始化輔助數組
            lowcost[i] = weight[1][i];
            closest[i] = 1;
            s[i] = false;
        }
        for(int i = 1; i < vexnum; i++) {
            float min = Float.MAX_VALUE;
            int j = 1;
            for(int k = 2; k <= vexnum; k++) {
                if((lowcost[k] < min) && (!s[k])) {//根據最小權加入新點
                    min = lowcost[k];
                    j = k;
                }
            }

            System.out.println("加入點" + j + ". " + j + "---" + closest[j]);//新加入點的j和與j相連的點

            s[j] = true;//加入新點j

            for(int k = 2; k <= vexnum; k++) {
                if((weight[j][k] < lowcost[k]) && !s[k]) {//根據新加入的點j,求得最小權
                    lowcost[k] = weight[j][k];
                    closest[k] = j;
                }
            }
        }
    }

最小生成樹加入結點的順序圖blog

3. 實驗過程當中遇到的問題和解決過程

  • 問題一:輸入結點時遇到空指針異常的拋出。
  • 問題一解決辦法:檢查代碼後發現是vexs[i] = input.next().charAt(0);這條語句使用前沒有初始化定義vexs[]數組的長度,致使這樣的錯誤。加上 vexs = new char[vexnum]; // vexnum長度的頂點數組 語句解決問題。後面的isVisited[]數組用來判斷是否訪問過的數組也趕上了一樣的問題,一樣方法解決。
  • 問題二:實驗過程當中對圖各個邊的權值進行賦值的操做問題
  • 問題二解決辦法:選擇使用二維數組,並將0行和0列設置爲0,不使用。便於後面程序編寫時的理解,給本身減小負擔。這個二維數組須要本身手動寫好在代碼裏,實際上是固定死本身的圖的樣子其餘樣式的圖就無法用。這個問題我還真不知道該怎麼解決。
  • 問題三:輸入時有些麻煩。尤爲是對邊進行輸入時(肯定哪些結點是相連的)
  • 問題三解決辦法:若是輸入錯誤,就要將程序從新開始,從新進行以前的全部步驟,很麻煩。我在寫這個代碼時候,加入了一些循環和判斷,來避免出現輸入錯誤致使程序直接結束。增長容錯率。可是有一些關鍵步驟,好比肯定邊,沒辦法用程序進行修正,仍是須要在輸入時當心。其實本身有一些設想,可是不知道怎麼實現。實現起來有一些麻煩。

其餘(感悟、思考等)

此次的實驗是將以前學過的許多內容進行結合和綜合運用,難度並非很大,可是須要細細思考和耐心理解。否則還有不少地方容易出錯。排序

相關文章
相關標籤/搜索