20172328 2018-2019《Java軟件結構與數據結構》第七週學習總結

20172328 2018-2019《Java軟件結構與數據結構》第七週學習總結

概述 Generalization

本週學習了第11章:二叉查找樹。在本章中,主要探討了二叉查找樹的概念和各類二叉查找樹實現,考察爲二叉查找樹添加和刪除元素的算法以及維護平衡二叉查找樹的算法html

教材學習內容總結 A summary of textbook

  • 二叉查找樹(binary search tree):二叉樹定義的擴展,一種帶有附加屬性的二叉樹。附加屬性是什麼?樹中的每一個節點,其左孩子都要小於其父節點,而父節點又小於或等於其右孩子。
  • 插入元素(addElement)java

    • (1)不容許插入相同關鍵字,若二叉查找樹中存在該關鍵字,則不插入node

    • (2)咱們能夠先檢索二叉樹,看查找樹中是否含有該關鍵字,若不存在,再作一次掃描將結點插入到適當位置。使用這種方式,爲插入一個該關鍵字,作了兩次掃描。git

    • (3)注意到,插入的結點老是做爲某一葉子節點的子結點,咱們能夠在第一次掃描過程當中就肯定待插入的位置,即把查找是否存在該關鍵字和查找可能的插入點在一次掃描中完成,提升插入效率。算法

  • 刪除元素(removeElement)
    在二叉查找樹中刪除一個給定的結點p有三種狀況:數組

    • (1)結點p無左右子樹,則直接刪除該結點數據結構

    • (2)結點p有左子樹(右子樹),則把p的左子樹(右子樹)接到p的父節點上學習

    • (3)左右子樹同時存在,找到結點p的中序直接後繼結點s,把結點s的數據轉移到結點p,而後刪除結點s,因爲結點s爲p的右子樹總最左的結點,於是s無左子樹,刪除結點s.測試

  • 平衡二叉查找樹:
    • 引入:爲何平衡假設很重要?若是樹不平衡,咱們的分析會出現什麼狀況?
    • 若是咱們的樹不平衡,那麼獲得的二叉樹實際上是一棵蛻化樹,看起來像鏈表,而且比鏈表的效率還低,由於每一個結點都附帶多於的開銷。addElement操做的複雜性爲O(n)。並且蛻化樹要浪費空間來存放那些未用的引用,而且不少算法會在沿着蛻化路徑前進以前檢查null引用。
    • 那麼該如何解決這個問題呢?
    • 咱們的目標是保持樹的最大路徑長度爲log2(n)。解決的辦法就是要有一個稱爲平衡的附加結構條件即:任何結點的深度不得過深。
    • 平衡二叉樹(Balanced Binary Tree)的定義:一棵平衡二叉樹是其每一個結點的左子樹和右子樹的高度最多相差1的二叉查找樹(空樹的高度爲-1),這個差值也稱爲平衡因子(本書定義的平衡因子:右子樹的高度減去左子樹的高度),當平衡因子大於1或者小於-1的時候以該結點爲樹根的子樹須要從新平衡。
    • AVL樹只是實現平衡二叉樹的一種方法,它還有不少的其餘實現方法如紅黑樹、替罪羊樹、Treap、伸展樹等。
  • 平衡化技術通用方法:
    • 右旋:
      • 使樹根的左孩子元素成爲新的根元素。
      • 使原根元素成爲這個新樹根的右孩子元素
      • 使原樹根的左孩子的右孩子,成爲原樹根的新的左孩子。
    • 左旋:
      • 使樹根的右孩子元素成爲新的根元素。
      • 使原根元素成爲這個新樹根的左孩子元素
      • 使原樹根的右孩子的左孩子,成爲原樹根的新的右孩子。
    • 右左旋:
      • 讓樹根右孩子的左孩子繞着樹根的右孩子進行一次右旋。
      • 而後再讓所得的樹根右孩子繞着樹根進行一次左旋。
    • 左右旋:
      • 讓樹根左孩子的右孩子繞着樹根的左孩子進行一次左旋。
      • 而後再讓所得的樹根左孩子繞着樹根進行一次右旋。
  • 運用這些平衡手段的條件
  • 旋轉發生的條件:
    • 左右子樹的高度差爲二,旋轉有兩種::單旋轉,雙旋轉。不管單旋轉仍是雙旋轉,都知足先進行與深度較高的子樹同名(右子樹對右旋轉)旋轉,若是是雙旋轉則隨後進行異名(右子樹對左旋轉)旋轉大數據

    • 單旋轉發生在:
    • ①插入時:
      • 插入的節點在不平衡點的左子樹的左子樹上(左單旋);在不平衡點的右子樹的右子樹上(右單旋)
    • ②刪除時:
      • 刪除左子樹的節點致使該點不平衡且其右子樹的右子樹存在時(右單旋);刪除右子樹的節點致使該點不平衡且其左子樹的左子樹存在時(左單旋)
    • 雙旋轉發生在:
    • ①插入時:
      • 插入的節點在不平衡點的左子樹的右子樹上(左右旋);在不平衡點的右子樹的左子樹上(右左旋)
    • ②刪除時:
      • 刪除左子樹的節點致使該點不平衡且其右子樹的右子樹不存在時(右左單旋);刪除右子樹的節點致使該點不平衡且其左子樹的左子樹不存在時(左右單旋)
  • 實現二叉查找樹:紅黑樹

  • 紅黑樹是一個更高效的檢索二叉樹,所以經常用來實現關聯數組。典型地,JDK 提供的集合類 TreeMap 自己就是一個紅黑樹的實現。
  • 紅黑樹控制結點顏色的規則以下:
    • 性質 1:每一個節點要麼是紅色,要麼是黑色。
    • 性質 2:根節點永遠是黑色的。
    • 性質 3:全部的葉節點都是空節點(即 null),而且是黑色的。(性質 3 中指定紅黑樹的每一個葉子節點都是空節點,並且葉子節點都是黑色 Java 實現的紅黑樹將使用 null 來表明,所以遍歷紅黑樹時將看不到黑色的葉子節點,反而看到每一個葉子節點都是紅色的。
    • 性質 4:每一個紅色節點的孩子結點都是黑色。(從每一個葉子到根的路徑上不會有兩個連續的紅色節點)
    • 性質 5:從任一節點到其子樹中每一個葉子節點的路徑都包含相同數量的黑色節點。(紅黑樹從根節點到每一個葉子節點的路徑都包含相同數量的黑色節點,所以從根節點到葉子節點的路徑中包含的黑色節點數被稱爲樹的「黑色高度」。)
    • 紅黑樹可以以O(log2(N))的時間複雜度進行搜索、插入、刪除操做。此外,任何不平衡都會在3次旋轉以內解決。這一點是AVL所不具有的。

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

  • 問題1:不明白書中removeElement方法中部分代碼的意思。書中解釋是:

    若是被刪除結點有兩個孩子,則返回中序後繼者(由於相等元素會放到右邊)

代碼是

  • 問題1的解決及過程:
    • 當結點的左右子樹都不空的時候,通常的刪除策略是用其右子樹的最小數據來代替要刪除的結點數據,並使得要刪除子樹的雙親結點指向找好的替代結點的子結點。
    • 老師在課堂上講了另外一種解決辦法: 當結點的左右子樹都不空的時候,找到該結點的前驅結點,而後將其前驅結點(用其左子樹的最大數據)做爲替代結點,而後讓要刪除子樹的雙親結點指向替代結點的子結點。
    • 前驅結點:該結點左子樹中的最大數據所在結點。
    • 後驅結點:該結點右子樹中的最小數據所在結點。
    • 整體來說:一棵二叉查找樹通過中序遍歷後是一個有序的、從小到大的列表。
  • 問題2:高度深度究竟有什麼區別?以前在學第十章:樹的時候曾和仇夏同窗討論過,可是沒有獲得明確的結果。當時老師上課講的是深度的概念,並且從root開始以1來計算、而書本上講的是樹的高度的概念,樹的高度是從跟結點到葉子結點之間的的最遠路徑長度,而且從root開始以0來計算。???
  • 問題2的解決:
    • 高度和深度一組相反的概念
    • 高度是指當前結點到葉子結點的最長路徑,如全部葉子結點的高度都爲0。
    • 深度則是指從根結點到當前結點的最大路徑長度,如根結點的深度爲0。
  • 因此,書上的講解和老師的講解其實都沒有問題,只是思惟理解上的問題。高度就是從要計算的結點開始尋找最遠路徑長度,深度就是從根結點到該結點的最大路徑長度;在一棵樹中,高度+深度 = 樹中最遠的路徑長度。
  • 問題3:紅黑樹的addElement操做和removeElement操做看書時沒有看太懂,好多疑惑。
  • 問題3的解決:經過週五早上老師上課的講解,以爲仍是聽懂了一些的。這裏稍加總結並配上老師的圖。

代碼實現時的問題做答 Exercise

  • 問題1:這周的代碼補全很容易理解,在我作完補全操做後,我又和個人小夥伴仇夏同窗訂對了一波,因而咱們發現了以前寫的findMin以及findMax因爲使用了以前寫的removeMin和removeMax的思路,在寫的時候其實有冗餘代碼。
  • 問題1的解決:刪掉冗餘代碼。

  • 問題2: 實現add自我遞歸時出現的錯誤。首先是死遞歸,其次是出現了一行不明錯誤提醒。

  • 問題2的解決:先是來解決不明錯誤提醒,我經過百度後得知:

    原來Junit4中的測試方法的方法名首字母不能大寫!!!

  • 經過修改代碼後,我發現是由於個人node直接定義成了root,因此在每次遞歸的時候又開始以前的路,就變成了死遞歸,在刪除代碼·node=root後測試就出來了。可是因爲toString問題沒有解決,我用了中序遍歷,可是仍是出現了很使人傷心的結果,但經過找最大最小值,看的出來,個人插入方法已經成功將1插入了二叉查找樹。

  • 問題3:上述問題2沒有實現樹型輸出,主要問題就在個人toString方法中,可是我沒有實現樹形狀的toString方法。
  • 問題3的解決:經過詢問郭愷同窗,借用了上週運算表達樹中PrintTree的輸出方法,稍做修改,就很完美的實現了樹形的正確輸出啦。

上週測試活動錯題改正 Correction

  • The binary tree shown above is balanced.
    A .True
    B .False
  • 這道題我真的沒有找到圖,因此不知道她平不平衡。因此沒啥好說的······給出的答案是true。

    碼雲連接

代碼量(截圖)

結對及互評Group Estimate

點評模板:

  • 博客中值得學習的或問題:
    • 20172301:博客反覆的在改動,尤爲是代碼問題上反覆在思考在修改描述,認真的對待博客正如認真的對待代碼。
    • 20172304: 對於學習知識點掌握應該是挺好的,上課時對問題反應很迅速。本次博客教材學習中的問題和解決過程和代碼問題都寫的不是很詳細,望繼續改進。

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

      今天早上的經濟學原理課程聽得我很快樂。範老師十分幽默風趣,講到了:在咱們面臨稀缺而選擇實現效益最大化時就要體現自身價值,在「萬類霜天競自由」的場景下是須要咱們去保持核心競爭力的。
      上課時我進行了自個人反問。從前,我從不想將本身放在與人競爭的位置,只想儘可能作好本身。至少在我看來,同人相比較是件不光彩的事,每一個個體沒有相同的軌跡和須要被比較的必要。但如今想來,在生活的時時刻刻我又未嘗不是處在競爭的環境下呢?因此,作好本身並不去打擾別人的努力,自我奮鬥去實現自身價值便可。至於對待結果的態度,從一而終。
      二叉查找樹這一章頗有意思也不太容易徹底理解。可是呢,事物的發展不是直線式前進的,而是螺旋式上升的。因此咱們既要看到道路的曲折,也要看到前途的光明!

      學習進度條Learning List

      代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積)
      目標 5000行 30篇 400小時
      第一週 0/0 1/1 8/8
      第二週 621/621 1/2 12/20
      第三週 678/1299 1/3 10/30
      第四周 2734/4033 1/4 20/50
      第五週 1100/5133 1/5 20/70
      第六週 1574/6707 2/7 15/85
      第七週 1803/8510 1/8 20/105

參考資料Reference

相關文章
相關標籤/搜索