1. 程式人生 > >2017-2018-20172309 《程式設計與資料結構》第九周學習總結

2017-2018-20172309 《程式設計與資料結構》第九周學習總結

2017-2018-20172309 《程式設計與資料結構》第九周學習總結

一、教材學習內容總結

一些概念:

  • : 是一種複雜的非線性資料結構。
  • 圖的二元組定義:
    • 圖 G 由兩個集合 V 和 E 組成,記為:
      G=(V, E) 其中: V 是頂點的有窮非空集合,
      E 是 V 中頂點偶對(稱為邊)的有窮集。

    • 通常,也將圖 G 的頂點集和邊集分別記為 V(G) 和 E(G) 。 E(G) 可以是空集。若 E(G) 為空,則圖 G 只有頂點而沒有邊。
  • 有向圖: 若圖 G中的每條邊都是有方向的,則稱 G 為有向圖 (Digraph) 。
  • 無向圖: 若圖G中的每條邊都是沒有方向的,則稱 G 為無向圖 (Undigraph) 。
  • 完全圖:
    • 無向圖中的每個頂點之間存在著一條邊,那麼這個圖是無向完全圖
    • 有向圖中的每兩個定點之間都存在著方向相反的兩條邊,則稱此圖為有向完全圖
  • 帶權圖:邊上具有權值的圖。
  • 最小生成樹:指的是有一個無向圖,根據這個圖構造一個包含所有頂點的樹,使得包含的邊的權值的和最小。
  • 最小路徑長度
    見下面教材中的問題!

圖的儲存:

  • 鄰接矩陣儲存法:採用2個數組來表示圖;一個是儲存所有頂點資訊的一維陣列(vetices[])、一個是儲存圖中頂點之間關聯關係的二維陣列(adjMatrix[][]),這個二維陣列稱為鄰接矩陣。

  1. 對於無向圖a,鄰接矩陣是一個對稱矩陣adjMatrix[i][j]==1,說明定點i與定點j是聯通的。
  2. 對於有向圖b,當a能到達b時,二維陣列adjMatrix[a][b]=1;
    • 鄰接矩陣的缺點:
      1. 閒置的單元浪費大量的空間:由n個頂點構成的圖中最多可以有n2條邊,但大多數情況下,邊的數目遠遠達不到這個量級,因此大多數單元都是閒置的.
      2. 矩陣結構是靜態的,大小N需要預先估計,然後建立N*N的矩陣,而圖的規模往往是動態變化的,N估計過大會造成空間浪費,過小則造成空間不夠用。
  • 鄰接列表儲存法
    :對於n個頂點、m條邊的無向圖,採用鄰接表,需要n個表頭節點和2m個邊表節點。在邊數少的情況下,要比使用鄰接矩陣節省空間。
  • 圖的遍歷:分為廣度優先遍歷深度優先遍歷

二、教材學習中的問題和解決過程

  • 問題1:書中有關integer的程式碼什麼意思?

  • 問題1解決方案:如圖:


    因為佇列中儲存的資料是Integer型別的,而numVerticesint型別的,因此應該轉化為Integer型,對應的方法為:

    那麼新的問題又來了:為什麼一定要Integer,直接用int不好嗎?
    答案:Integer是其包裝類,注意是一個類。而int 是基本資料型別.我們使用integer是為了在各種型別間轉化,通過各種方法的呼叫

  • 問題2:如何理解廣度、深度優先遍歷?
  • 問題2解決方案:
    • 廣度優先遍歷:左看看、又看看,雨露均沾
      • 虛擬碼:
      1. 初始化佇列:visited[n] = 0
      2. 訪問頂點:visited[v] = 1
      3. 頂點v加入佇列
      4. 迴圈:
        while(佇列是否為空)
            v = 佇列頭元素
            w = v的第一個鄰接點
            while(w存在)
                if(如果w未訪問)
                    visited[w] = 1;
                    頂點w加入佇列
                    w = 頂點v的下一個鄰接點
    • 深度優先遍歷:一條路走到底。
      • 虛擬碼:
      1. 訪問陣列初始化:visited[n] = 0
      2. 訪問頂點:visited[v] = 1
      3. 取v的第一個鄰接點w;
      4. 迴圈遞迴:
           while(w存在)
               if(w未被訪問過)
               從頂點w出發遞迴執行;
             w = v的下一個鄰接點;
  • 問題三:如何理解迪傑斯特拉演算法
  • 解決方法:
    • 感覺這裡講的非常好.
    • 所以我還是自己簡單總結下吧。
      • 這個演算法是用來計算兩點之間的最短路徑的,生活中多用來計算兩地之間的來往的最少車費。
      • 它的主要特點是以起始點為中心向外層層擴充套件(廣度優先搜尋思想),直到擴充套件到終點為止。
      • 舉個例子吧:

程式碼除錯中的問題和解決過程

  • 問題1:如何判斷圖的的一個圖是否連通?
  • 問題1解決方案:
    • 如果是連通的,當且僅當使用廣度優先遍歷中的定點數等於圖中的頂點數。
    • 因此,我們只要定義一個int值,當每遍歷一個頂點,就加一。遍歷完成後,看該值是否等於頂點數就OK啦。
    • 程式碼實現
    public boolean isConnected()
     {
         boolean result = true;
         for(int i=0;i<numVertices;i++){
             int temp=0;
             temp=getSizeOfIterator(this.iteratorBFS(vertices[i]));
             if(temp!=numVertices)
             {
                 result = false;
                 break;
             }
         }
         return result;
     }
  • 問題2:完成pp15.1過程中 出現 邊不顯示空指標兩個問題!

  • 問題2解決方案:首先 肯定是 輸出方法出現了問題,解決後發現應該這樣:

    然後出現的問題是:

    經分析:肯定是哪句程式碼錯了:導致全部連在一起了!

    值得注意的是 在無向圖中新增邊,應該兩邊的聯絡都要考慮:

 public void addEdge(int index10 , int index20){
       int  index1 =index10-1;
       int  index2 =index20-1;
        if (indexIsValid(index1)&&indexIsValid(index2)){
            GraphNode temp = vertices[index1];//得到首結點

            while (temp.getNext()!=null){
                if (temp.getNext().getElement() == vertices[index2].getElement()) {
                    System.out.println("已存在該邊!");
                    break;
                }
                    temp = temp.next;
            }
            temp.next = new GraphNode(vertices[index2].getElement());//有index10--》index20
                

            GraphNode temp2 = vertices[index2];

            while (temp2.getNext()!=null){
                if (temp2.getNext().getElement() == vertices[index1].getElement()) {
                    System.out.println("已存在該邊!");
                    break;
                }
                temp2 = temp2.next;
            }
            temp2.next = new GraphNode(vertices[index1].getElement());//有index20--》index10
        }

        modCount++;
    }

程式碼之家

課本上的程式碼:

程式碼託管

(statistics.sh指令碼的執行結果截圖)

上週考試錯題總結

第十二章錯題

Since a heap is a binary search tree, there is only one correct location for the insertion of a new node, and that is either the next open position from the left at level h or the first position on the left at level h+1 if level h is full.
A .True
B .Flase

錯誤原因:堆是一棵完全二叉樹、不是一顆二叉搜尋樹。自己瞎了眼!!!!

點評模板:

部落格或程式碼中值得學習的或問題:

- 
- 
- 

點評過的同學部落格和程式碼

  • 本週結對學習情況
    • 20172310
    • 結對學習內容
      • 是十五章--圖
      • 瞭解圖的運用--加權圖:航線問題
      • 瞭解圖的遍歷。
  • 上週部落格互評情況

其他(感悟、思考等,可選)

這一章內容比較簡單,或者可以說書上的內容比較簡單,但是實現起來很難。也可能是書上的例子比較少的原因。還有就是發現裡面的幾個演算法是非常有意思的,比如Dijkstra演算法。它能通過實際的幾個陣列就能找到最短路徑!!!很驚訝!!!

學習進度條(上學期截止7200)

程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 260/0 1/1 05/05
第二週 300/560 1/2 13/18
第三週 212/772 1/4 21/39
第四周 330/1112 2/7 21/60
第五週 1321/2433 1/8 30/90
第六週 1024/3457 1/9 20/110
第七週 1024/3457 1/9 20/130
第八週 643/4100 2/11 30/170

參考資料

  1. 如何判斷圖是否完全
  2. Dijkstra 演算法
  3. 迪傑斯特拉演算法介紹