2017-2018 20172309 《程序設計與數據結構(下)》第七章學習總結

2017-2018 20172309 《程序設計與數據結構(下)》第七章學習總結

1、教材學習內容總結

1.1關於二叉查找樹的一些概念

  • 二叉查找樹具備附加屬性,其左孩子小於父節點、而父節點又小余或者等於右結點。
  • 所以二叉查找樹的最右側會存放最大元素、而其最左側會存放最小元素。
  • 二叉查找樹是二叉樹的擴展,它絕大數方法都會用到遞歸,二叉查找樹的平均查找深度爲O(log2N).html

    1.2實現二叉查找樹

  • 添加元素(addElement操做)
    • 插入方法首先在插入的時候判斷被插入元素的類型是否是Comparable類if (!(element instanceof Comparable)),若是不是則會拋出NoComparableException
      1. 若是根結點爲null,被插入元素成爲根結點。
      1. 根結點不爲null,將使用comparaTo()方法與TargetElement進行比較,
      1. 獲得的結果爲-一、1時,分別放在父節點的左子樹、和右子樹。
      1. 而後繼續跟接下來的結點進行比較,即重複步驟a、b、c。
    • 就像這樣:
  • 刪除操做(removeElement操做)
    • 刪除操做將在二叉查找樹中刪除給定的Comparable元素,若是找不到、將拋出ElemenNotFoundException.
    • 查找到要刪除的元素以後刪除操做分爲三種狀況:
      • 沒有左右子節點,能夠直接刪除這個結點。好比刪除結點20.
        java

      • 存在左節點或者右節點,刪除該節點後其父結點與子節點鏈接。好比刪除結點70。
      • 同時存在左右子節點,將用其右子樹中最小的結點與之交換。好比刪除結點30.
      1. 當咱們將上面的二叉查找樹使用中序遍歷遍歷時,獲得的結果爲上面的鏈表。
      2. 當咱們刪除結點30的時候,鏈表中32以後的全部結點都將往前移動一個位置,並且結點32是結點30以後的結點中最小的一個,所以它將成爲代替被刪除的那個結點。即:
      3. 結點替換後,原來的結點32將被刪除。
  • removeAllOccurrencesremoveMinremoveMaxfindMaxfindMin方法都在:LinkedBinarySearchTree類git

    1.3用有序列表實現二叉樹

  • 樹的做用之一是爲其餘集合提供高效的實現。
  • 樹的使用實現集合會讓有些操做變得高效,也會讓一些操做變得低效:數據結構

操做 LinkList BinarySearchTreeList
removeFirst O(1) O(n)
removeLast O(n) O(n)
remove O(n) O(n)
first O(1) O(n)
last O(n) O(n)
contains O(n) O(n)
isEmpty O(1) O(1)
size O(1) O(1)
add O(n) O(n)

黑色加粗表明使用樹後操做將變得低效。學習

紅色字體表明該操做可能使樹變得不平衡。字體

1.4AVL樹

  • 二叉查找樹的平衡很重要!不平衡時,當咱們插入一個已經排好序的一組數字時,它會變成一個相似於鏈表的結構。如圖:

    若是查找二叉樹不平衡,其效率可能比線性結構還要低!由於每一個結點還有額外的開銷。
  • 要解決這個問題,咱們有以下規定: 任何結點不得過深,即:任何結點的平衡因子的絕對值不能超過1;(平衡因子:左子樹的高度減去右子樹的高度)
    • 幾個例子以下圖:
  • AVL樹的插入操做首先會按照普通搜索二叉樹的插入操做進行,當插入一個數據後,咱們會沿着插入數據時所通過的的節點回溯,回溯的過程當中會判回溯路徑中的每一個節點的左子支高度與右子支高度之差的絕對值是否超過1,若是超過1咱們就進行調整,調整的目的是使得該節點知足AVL樹平衡的定義。調整的狀況能夠分爲如下四旋轉操做。
    • 左旋:以某一個節點爲軸,它的右子枝逆針旋轉,做爲新子樹的根,咱們稱之爲左旋。
      • 節點X右子支比左子支高度大2,且插入的節點位於節點X右孩子節點XR的右子支上。
    • 右旋:以某一個節點爲軸,它的左子枝順時針旋轉,做爲新子樹的根,咱們稱之爲右旋。
      • 節點X左子支比右子支高度大2,且插入的節點位於X的左孩子節點XL的左子支上。
    • 左右旋:先通過一次左旋,而後通過一次右旋。
      • 節點X左子支比右子支高度大2,且插入的節點位於節點X左孩子節點XL的右子支上。
    • 右左旋:先通過一次右旋,再通過一次左旋。
      • 節點X左子支比右子支高度大2,且插入的節點位於節點X左孩子節點XL的右子支上
  • AVL樹的實現:BinaryAVLTree
  • 關於紅黑樹
    • 見下面教材中的問題。

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

  • 問題1:如何理解紅黑樹?它的功能AVL樹也能實現,要這玩意兒幹嗎?
  • 問題1解決方案:
    • 認識紅黑樹:(書中的什麼概念就不說了,就說說本身的理解吧。)紅黑樹的特色是須要進行復雜的顏色變化、以及在AVL樹中的旋轉,可是它的出現解決了AVL樹維護慢、空間開銷大的不足。
    • 如今咱們來總結紅黑樹與AVL樹的區別吧!
      1. AVL樹又稱爲平衡二叉搜索樹,他是一棵空樹或者兩子樹的高度差絕對值不超過1.而紅黑樹用顏色標識高度,不是嚴格平衡的!
      2. 雖然AVL樹的效率很高,但紅黑樹的效率更高。(例如:當進行刪除操做而引發樹不平衡時,AVL樹最壞狀況下須要維護從該節點到根結點全部節點的平衡,於是旋轉的量級爲(log2 N);而紅黑樹對於任何不平衡最多隻須要旋轉三次!)。
      3. 紅黑樹的查詢性稍微遜色於AVL樹,由於它比AVL樹會稍微不平衡多一層,也就是說他會比AVL樹多進行一次比較。ui

        結論來自這!.net

    • 總而言之,他雖然複雜,可是它的效率總的來講比AVL樹高。

代碼調試中的問題和解決過程

  • 問題1:在網上看代碼時,發現了個問題:comparator中的comparable方法與平時用的comparaTo方法的異同點?
  • 問題1解決方案:
    • comparator這個東西是在網上看別人代碼時看到的,他是做爲一個比較器,我當時的疑問是爲啥要這個東西,用ComparaTO這個方法不就行了麼?如圖:

      在以後的實驗中我沒有寫這個構造器,準備使用ComparaTO方法,而後發現:

      調用不了ComparaTO方法,是由於只能這樣用String1.comparaTO(String2)...,也就是隻能比較String類型。要想比較其餘類型,就得寫一個比較器,其中用Compara(T value1,T value2)方法。
  • 問題2:如何實現左旋和右旋?
  • 問題2解決方案:
    • 額,這個東西書好像是看懂了,可是敲起代碼來並無那麼容易,而後到網上找了找,根據是由有parent(是不是雙指針)分爲兩種。
    • 第一種:有parent:

      這種方法,每一次當父節點指向新的子節點時,子節點也要指向父節點。
    • 第二種:沒有parent:

      這種沒有parent指針的方法,雖然看起來簡單,但當它不能調用叔叔結點!有parent指針的能夠,好比:
  • 問題三:在二叉查找樹中添加元素時,當添加已有元素或者添加兩個相同元素時會發生什麼狀況?當添加比它小的元素時,這個小的元素會出如今這兩個相同元素的左邊?(好比添加了兩個相同的元素5後,在添加一個元素3,那麼這個3在哪一個5的左邊?)
  • 問題3解決方案:
    對於添加已有結點或相同結點能夠分類討論:
    • 一:當添加已有結點時,後來的數據之間覆蓋原來的數據,有可能人說這個沒有用,在我看來,當一個節點有兩個數據時,這就變得很是有用,好比這兩個數據是:name、price。設計

      已有的數據爲:name:牛奶 、price:2元
      後來的數據爲:name:牛奶 、 price:2.5 元
      通常來講、在實際生活中的應用一個節點會有不少數據,因此通常不會所有相同的。所以更新尤其重要。3d

    • 二:在書中代碼上,數據不會更新的。相同的元素會放在原元素的右結點上,當放上比他小的元素時,會存在於它的第一個出現的結點的左節點上。

代碼託管

上週考試錯題總結

  • 本週錯題暫沒出答案!

點評模板:

博客或代碼中值得學習的或問題:

- 隊友對於本身不懂得問題懂得深究,好比同窗、百度。
- 隊友的事比我多、學習java的效率比我高。
- 隊友很細心、可以發現一些小問題。

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20172310
    • 結對學習內容
      • 二叉查找樹~
      • 平衡二叉查找樹(AVL樹)
      • 紅黑樹
  • 上週博客互評狀況

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

在上一章中,我說那一章很難。如今想是我錯了!這個十一章是難的我腦袋都疼!特別是那個AVL、紅黑樹,哎。我得看代碼去了····

學習進度條(上學期截止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
第七週 900/4357 1/9 20/130

參考資料

相關文章
相關標籤/搜索