20182333 2019-2020-1 《數據結構與面向對象程序設計》第十週學習總結

20182333 2019-2020-1 《數據結構與面向對象程序設計》第十週學習總結

教材學習內容總結

  • 與樹相似,圖由結點和這些結點之間的鏈接構成。
  • 頂點(vertice):就是結點。
  • 邊(edge):就是這些結點鏈接起來的線段。
  • 路徑(path):圖中的一系列邊,每條邊連通兩個頂點。
  • 路徑的長度(length):是該路徑中邊的條數(或者是頂點數減去1)。
  • 環路(cycle):一種首結點和末結點相同且沒有重邊的路徑。沒有環路的圖稱爲無環的(acyclic)。
  • 徹底圖(complete graph):含有最多條邊的無向圖

無向圖

  • 邊沒有方向的圖稱爲無向圖。
    html

  • 無向圖中,表示邊的頂點對是無序的,例如,標記頂點A,B,C,D,一條邊能夠表示爲(A,B)。無向圖表示頂點對是無序的,因此邊(A,B)意味着A和B之間的鏈接是雙向的,在一個無向圖中,(A,B)和(B,A)所表明的邊的含義徹底同樣。
  • 含有最多條邊的無向圖稱爲徹底圖:Edges=(n-1)*n/2.
    java

  • 若是無向圖中任意兩個頂點間都有路徑,則無向圖稱爲連通的。
  • 路徑是鏈接圖中兩個頂點的邊的序列,路徑長度爲路徑所含邊的數目(頂點個數減一)
  • 第一個頂點和最後一個頂點是同一個頂點且沒有重複邊的路徑,稱爲一個環。
  • 若是圖中兩個頂點之間有邊鏈接,則稱這兩個頂點是鄰接的(鄰居),本身鏈接到本身的邊稱爲自循環或懸掛。git

有向圖

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

  • 頂點是有序對的圖稱爲有向圖,有向圖的每條邊都帶有一個移動方向,這個方向有頂點的順序指定,因此(A,B)表示只容許從A移動到B,但不容許另外一個方向的移動。
  • 樹就是圖,樹的大部分工做是針對有向樹。有向樹是一個有向圖。數組

  • 如上圖:a是強連通,b是單向連通,c是弱連通。

帶權圖

  • 每條邊都對應一個權值的圖成爲帶權圖,有時也成爲網絡。
  • 無向帶權圖
    服務器

  • 有向帶權圖
    網絡

經常使用的圖的算法

  • 圖的遍歷:
    • 廣度優先遍歷:從一個頂點開始,輻射狀地優先遍歷其周圍較廣的區域。就如同樹中的層次遍歷。
    • 深度優先遍歷:圖的深度優先搜索,相似於樹的先序遍歷,所遵循的搜索策略是儘量「深」地搜索圖。就如同樹中的前序遍歷。
  • 測試連通性:
    • 連通性:圖中的任意兩個頂點之間都存在一條路徑,則認爲這個圖是連通的。
    • 測試方法:
      • 從任意結點開始的廣度優先遍歷中獲得的頂點數等於圖中所含頂點數。
  • 生成樹(spanning tree):包含圖中全部頂點及圖中部分邊的一棵樹。
  • 最小生成樹(minimum spanning tree):所含邊權值之和小於其餘生成樹的邊的權值之和。
    • Prim算法和Kruskal算法
  • 斷定最短路徑:
    • 斷定起始頂點和目標頂點之間是否存在最短路徑(兩個頂點之間邊數最少的路徑)。
    • 在加權圖中找到最短路徑。(Dijkstra算法)
  • 圖的實現策略:
    • 鄰接列表:用一種相似於鏈表的動態結點來存儲每一個結點帶有的邊。這種鏈表稱爲鄰接列表。
    • 鄰接矩陣:用一種叫鄰接矩陣的二維數組來表示任意兩個頂點的交接狀況。
    • 無向圖的鄰接矩陣必定是對稱的,有向圖的鄰接矩陣不必定對稱。
    • 十字鏈表法數據結構

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

  • 問題1:圖的遍歷與樹的遍歷有什麼區別?
  • 問題1解決方案:樹是有序的,圖是無序的。圖有兩種遍歷方法,一種是廣度優先遍歷,另外一種是深度優先遍歷。對於樹來講,它的廣度優先遍歷就是層序遍歷,深度優先遍歷就是先序遍歷。
  • 問題2:無向圖中的連通和徹底之間的關係是什麼。
  • 問題2解決方案:學習

    1.徹底是任意兩個頂點之間都會有一條邊。
     2.連通是任意兩個頂點之間都存在一條路徑。
     3.徹底的必定連通。
  • 問題3:如何理解廣度、深度優先遍歷?
  • 問題3解決方案:測試

    • 廣度優先遍歷:左看看、又看看,雨露均沾。

    • 僞代碼:
    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;
         }

代碼託管

上週考試錯題總結

上週沒有考試,因此沒有錯題。

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20182317
    • 20182318
    • 結對學習內容
      • 如何畫十字鏈表以及鄰接矩陣
      • 圖的廣度和深度優先遍歷
      • 如何使用Prim算法和Kruskal算法計算最小生成樹
  • 上週博客互評狀況

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

本週主要學習了圖的知識,例如如何畫鄰接矩陣、十字鏈表和鄰接鏈表。如何計算圖的廣度優先遍歷和深度優先遍歷。還有用Prim算法和Kruskal算法計算最小生成樹等等。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 10000行 30篇 400小時
第一週 56/56 2/2 20/20 主要學會了簡單的操做Linux以及如何編寫簡單的java程序並將它上傳到碼雲
第2、三週 331/407 3/5 23/43 學會了一些類和程序包的使用,也明白了C語言和Java在有些地方的區別
第四周 595/1002 2/7 20/60 學會了IDEA以及用IDEAgit碼雲,也學會了TDD測試
第五週 1621/2623 2/9 17/77 見識了服務器與用戶連接的代碼,也學習了繼承的一些知識。
第六週 1770/4393 1/10 22/99 學習了多態以及與接口和繼承的關係,還有就是對異常的學習和處理異常的方法以及自定義一個異常
第七週 1747/6140 3/13 23/122 學習了漸進複雜度的計算,棧和隊列的學習,分別用數組和鏈表實現隊列
第八週 384/6524 1/14 20/142 學習了一些查找和排序的算法,也學會了計算ASL
第九周 1895/8419 3/17 22/164 學習了樹的四種遍歷,和怎樣根據已知序列求未知序列等等
第十週 1946/10365 3/20 22/183 學習瞭如何求圖圖的廣度和深度優先遍歷,以及如何用Prim算法和Kruskal算法計算最小生成樹等等。
  • 計劃學習時間:20小時

  • 實際學習時間:22小時

  • 改進狀況:無

參考資料

相關文章
相關標籤/搜索