1. 程式人生 > >20172322 《程式設計與資料結構》第七週學習總結

20172322 《程式設計與資料結構》第七週學習總結

20172322 《程式設計與資料結構》第七週學習總結

教材學習內容總結

本章的內容主要講二叉查詢樹,二叉查詢樹是對於二叉樹的一種拓展,這意味著上一章中對於二叉樹的操作對於二叉查詢樹同樣適用,同時它也是一種帶有附加屬性的二叉樹。這種附加屬性即:對樹中的每個結點,它的左孩子都要小於其父結點,而父結點又小於或等於它的右孩子這意味著在所有比根結點大的元素都存在於根結點的左邊,而比根結點小的元素都在根結點的右邊。如圖所示:

值得一提的是,對二叉查詢樹進行中序遍歷,正好可以得到一隊遞增排序的元素。

例如,對於之前所示二叉查詢樹進行中序遍歷可以等到:1,3,4,6,7,8,10,13,14。

  • 二叉查詢樹的查詢演算法:因為二叉查詢樹的每個結點都具有特殊性質,所以說所有的元素都是以一定的順序存在於二叉查詢樹中,所以對於比根結點大的元素就去根結點的左子樹查詢,對於比根結點小的元素就去根結點的右子樹查詢,這個演算法如果使用遞迴實現會非常方便。

例如,查詢10

1.檢視根節點9:

2.由於10 > 9,因此檢視右孩子13:

3.由於10 < 13,因此檢視左孩子11:

4.由於10 < 11,因此檢視左孩子10,發現10正是要查詢的節點:

  • 二叉查詢樹的插入演算法:因為二叉查詢樹是一個其結點具有特定屬性的二叉樹所以它的插入演算法就只需要一個方法,我覺得二叉查詢樹與有序列表類似,僅需一個addElement方法就可以把一個元素插入正確的位置。具體的解決方案是:
    • 首先執行查詢演算法,找出被插結點的父親結點。
    • 判斷被插結點是其父親結點的左、右兒子。將被插結點作為葉子結點插入。
    • 若二叉樹為空。則首先單獨生成根結點。
  • 二叉查詢樹的刪除演算法:刪除結點有三種情況分別是需要刪除的結點是葉結點,是僅有左子樹/右子樹的結點,是既有左子樹又有右子樹的結點。
    • 刪除的結點是葉結點,直接讓樹結點的父結點的下一個指向null即可。
    • 刪除的結點是僅有左子樹/右子樹的結點,將該節點刪除後,將該結點的左結點/右結點提到被刪除結點的位置即可。
    • 刪除的結點是既有左子樹又有右子樹的結點,這個時候需要用到中序遍歷後的前驅結點,將前驅結點提到被刪除結點的位置。
  • 平衡二叉查詢樹,它存在的意義在於提升效率,例如,一棵蛻化樹看起來更像一個連結串列但是它的效率比連結串列還差。

    • 如圖所示,

    • 對於一個平衡二叉查詢樹來說,它的查詢效率會比第二種蛻化樹高很多,因為在蛻化樹中的每個結點附帶有額外的開銷,所以說我們就要想著將一些樹儘可能的改變為平衡二叉查詢樹。將一個費平衡二叉查詢樹改變成為二叉查詢樹主要有四種方法:右旋,左旋,左右旋,右左旋。
      • 在提到四種方法之前,有一個概念需要理解,一個平衡二叉查詢樹的最大路徑長度應該為log2n(n為元素個數),並且最長路徑必須不小於log2n-1(n為元素個數),如果一個樹的最長查詢路徑大於log2n則表明它不平衡,這時候就需要一定的操作使其平衡。

      • 右旋,通常是指左孩子繞著其父結點向右旋轉,一般適用於左子樹長於右子樹的情況

      • 左旋,通常是指右孩子繞著其父結點向左旋轉,一般適用於右子樹長於左子樹的情況

  • AVL樹,在之前的基礎上添加了平衡因子的說法,即左右子樹的高度差,如果高度差大於1或者小於-1,則以該結點為樹根的子樹需要重新平衡。

  • 黑樹,顧名思義,即給每個結點賦以和黑兩種顏色,對於黑樹的三點規定如下,
    • 根結點為黑色。
    • 紅色節點的孩子為黑色。
    • 樹根到樹葉的每條路徑都包含同樣樹木的黑色結點
  • 黑樹的插入,總是把插入的新元素的顏色設為紅色,在插入過後極大可能會導致一系列操作以再次平衡黑樹。
  • 黑樹的刪除,與插入類似,刪除一個元素後有極大可能需要一系列操作以再次平衡黑樹。

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

  • 問題一:對於黑樹存在的意義問題,為什麼要單獨設定一個黑樹呢?紅黑樹可以解決的問題AVL樹也同樣可以解決。
  • 問題一解決方案:這個問題我在網上查找了部分答案,發現為什麼需要發明紅黑樹。
    • 最主要就是效率問題,紅黑樹並不追求“完全平衡”——它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了效能。
    • 當然這也不是沒有代價的,紅黑樹是犧牲了嚴格的高度平衡的優越條件為代價讓紅黑樹能夠以O(log2 n)的時間複雜度進行搜尋、插入、刪除操作。

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

  • 問題一:對於AVL樹的實現存在一些問題,原本以為書上所給的程式碼已經實現了AVL樹,就好像那個addElement(T element)一樣。
  • 問題一解決:詢問了結對夥伴,發現好像不是這樣的,addElement(T element)這個方法只能一直新增元素,但不能使得元素成為平衡樹,就好像如果一直利用這個方法新增遞減的元素會導致蛻化樹的出現。
  • 問題二:對於AVL樹的實現有一些疑惑,它的左旋、右旋、左右旋、右左旋怎麼實現?
  • 問題二解決:班主任在藍墨雲上的資源《紅黑樹(五)之 Java的實現》的博主對於樹的實現有一系列的東西,不只是紅黑樹,我在其部落格中找到了《AVL樹(三)之 Java的實現》,借鑑了博主的部分程式碼,並且看懂了他們,感謝博主

程式碼託管“點這裡跳轉到碼雲”

上週考試錯題總結

  • 錯題1:A find operation on a balanced binary search tree is O(logn) where as a find operation for binary search tree without the balance assumption is O(n).
  • A.True
  • B.False
  • 錯題1解析:平衡樹查詢的時間複雜度就是O(logn)

  • 錯題2是那一道沒有圖的題。

結對及互評(待修改)

  • 部落格中值得學習的或問題:
    • 範雯琪同學的部落格課本上的學習內容總結部分寫得十分詳細,值得學習。
    • 每次看到範雯琪同學的部落格自己都比較慚愧,實在是非常優秀,可想而知她在部落格這一方面所做出的努力,我也非常想想她學習。
  • 程式碼中值得學習的或問題:
    • commit提交的解釋清晰明瞭,我覺得我應該學習。
    • 有許多程式碼的問題都是我向她詢問,我很感謝她

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

  • 本週結對學習情況
    • 20172303

    • 結對學習內容
      • 我們一起實現了本週需要實現的一些PP專案並且給互相講述了其中的基本原理。

其他

  • 感悟:感覺自己在程式碼上的問題越來越少了...快要找不出問題了,怎麼辦...一定是我學得還不夠認真

課本單詞

(本部分用於收集本章節後的生詞)

  • binary search tree:二叉查詢樹
  • degenerate tree:蛻化樹
  • right rotation:右旋
  • left rotation:左旋
  • rightleft rotation:右左旋
  • leftright rotation:左右旋
  • AVL tree:AVL樹
  • balance factor:平衡因子
  • red/black tree:紅黑樹

學習進度條

程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/5000 2/2 8/8 認真學習!積極向上
第二週 812/812 1/3 22/30
第三週 814/1626 1/4 20/50
第四周 1386/3012 2/6 20/70 愉快的國慶節就要結束了...
第五週 1222/3234 1/7 30/100
第六週 1327/4561 2/7 30/100 啦啦啦啦啦
第七週 1170/5631 1/8 33/133
  • 計劃學習時間:25小時

  • 實際學習時間:33小時

  • 改進情況:規範commit行為,改進部落格園模版。

參考資料