2017-2018-20172309 《程式設計與資料結構》第九周學習總結
阿新 • • 發佈:2018-11-19
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[][]),這個二維陣列稱為鄰接矩陣。
- 對於無向圖a,鄰接矩陣是一個對稱矩陣,adjMatrix[i][j]==1,說明定點i與定點j是聯通的。
- 對於有向圖b,當a能到達b時,二維陣列adjMatrix[a][b]=1;
- 鄰接矩陣的缺點:
- 閒置的單元浪費大量的空間:由n個頂點構成的圖中最多可以有n2條邊,但大多數情況下,邊的數目遠遠達不到這個量級,因此大多數單元都是閒置的.
- 矩陣結構是靜態的,大小N需要預先估計,然後建立N*N的矩陣,而圖的規模往往是動態變化的,N估計過大會造成空間浪費,過小則造成空間不夠用。
- 鄰接矩陣的缺點:
- 鄰接列表儲存法
- 圖的遍歷:分為廣度優先遍歷與深度優先遍歷。
二、教材學習中的問題和解決過程
問題1:書中有關integer的程式碼什麼意思?
問題1解決方案:如圖:
因為佇列中儲存的資料是Integer
型別的,而numVertices
是int
型別的,因此應該轉化為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++;
}
程式碼之家
課本上的程式碼:
程式碼託管
- pp15.7:
(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
錯誤原因:堆是一棵完全二叉樹、不是一顆二叉搜尋樹。自己瞎了眼!!!!
點評模板:
部落格或程式碼中值得學習的或問題:
-
-
-
點評過的同學部落格和程式碼
其他(感悟、思考等,可選)
這一章內容比較簡單,或者可以說書上的內容比較簡單,但是實現起來很難。也可能是書上的例子比較少的原因。還有就是發現裡面的幾個演算法是非常有意思的,比如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 |