20172311《程序設計與數據結構》第七週學習總結

20172311《程序設計與數據結構》第七週學習總結

教材學習內容總結

第十一章 二叉查找樹

  • 二叉查找樹是一種含有附加屬性的二叉樹,即其左孩子小於父節點,而父節點又小於等於右孩子
  • 二叉查找樹的UML描述
  • addElement操做
  • removeElement操做
    html

  • 用有序列表實現二叉查找樹體現了樹爲其餘集合提供高效實現的用途
  • 有序列表的鏈表實現分析和二叉查找樹實現分析
    java

  • 若是二叉查找樹不平衡,其效率可能比線型結構的還要低。能夠經過左旋、右旋、左右旋、右左旋解讓樹平衡化
  • 左旋
    git

  • 右旋
    面試

  • 左右旋
    算法

  • 右左旋
    編程

  • AVL樹是樹的一種變體,對於樹中的每一個節點咱們都會跟蹤記錄其左右子樹的高度,對於書中任何結點若是其平衡因子(即右子樹高度減去左子樹高度)——大於1或者小於-1,則以該節點爲樹根的子樹須要從新平衡。
  • 樹(或樹的任何子樹)只有兩種途徑能變得不平衡:插入節點或刪除節點
  • AVL樹的右旋
    數組

  • AVL樹的右左旋
    數據結構

  • 二叉查找樹的另外一種實現是紅黑樹,紅黑樹是一種平衡二叉查找樹,其中每一個節點存儲一種顏色(紅色或黑色,一般用一個布爾值來實現,值false等價於紅色)。控制節點顏色的規則以下ide

    一、每一個結點或是紅色的,或是黑色的
    二、根節點是黑色的
    三、每一個葉結點(NIL)是黑色的
    四、若是一個節點是紅色的,則它的兩個兒子都是黑色的。
    五、對於每一個結點,從該結點到其葉子結點構成的全部路徑上的黑結點個數相同。性能

  • 某種程度上,紅黑樹中的平衡限制沒有AVL樹那麼嚴格。可是,它的序仍然是logn。
  • 紅黑樹示意圖以下:

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

  • 問題1:AVL樹與紅黑樹之間的聯繫與區別在哪
  • 問題1解決方案:
  • 紅黑樹與AVL樹的比較:

1.AVL是嚴格的平衡樹,所以在增長或者刪除節點的時候,根據不一樣狀況,旋轉的次數比紅黑樹要多;
2.紅黑樹是用非嚴格的平衡來換取增刪節點時候旋轉次數;
3.因此若是你的應用中,搜索的次數遠遠大於插入和刪除,那麼選擇AVL樹,若是搜索,插入刪除次數幾乎差很少,應選擇紅黑樹。即,有時僅爲了排序(創建-遍歷-刪除),不查找或查找次數不多,R-B樹合算一些。
4.紅黑樹與AVL樹的調整平衡的實現機制不一樣,AVL靠平衡因子和旋轉,紅黑樹靠節點顏色以及一些約定再加上旋轉。所以,存在去掉顏色的紅黑樹後它不是AVL樹,好比左子樹都是黑的,右子樹都是紅黑相間的,這樣整個樹高度2n的時候,根節點的左右層數差能夠到n。

  • 紅黑樹(RB-tree)比AVL樹的優點在哪?

    紅黑是用非嚴格的平衡來換取增刪節點時候旋轉次數的下降,任何不平衡都會在三次旋轉以內解決,而AVL是嚴格平衡樹,所以在增長或者刪除節點的時候,根據不一樣狀況,旋轉的次數比紅黑樹要多。因此紅黑樹的插入效率更高。紅黑樹可以以O(log2 n) 的時間複雜度進行搜索、插入、刪除操做。紅黑樹的算法時間複雜度和AVL相同,但統計性能比AVL樹更高。所以,若是你的業務中查找遠遠多於插入、刪除,那選AVL樹;若是查找、插入、刪除頻率差很少,那麼選擇紅黑樹。

  • 問題2:沒法理解課本上給出的紅黑樹的插入操做

  • 問題2解決方案:查閱資料總結以下

    插入過程

默認插入的結點爲紅色。爲什麼?
由於紅黑樹中黑節點至少是紅節點的兩倍,所以插入節點的父節點爲黑色的機率較大,而此時並不須要做任何調整,所以效率較高。

1. 父爲黑

插入後無需任何操做。因爲黑節點個數至少爲紅節點的兩倍,所以父爲黑的狀況較多,而這種狀況在插入後無需任何調整,這就是紅黑樹比AVL樹插入效率高的緣由!

2. 父爲紅

父爲紅的狀況破壞了紅黑樹的性質,此時須要根據叔叔的顏色來作不一樣的處理。

1.叔叔爲紅

此時很簡單,只需交換爸爸、叔叔和爺爺的顏色便可。
此時若爺爺節點和太爺爺節點顏色相同,再以爺爺節點爲起始節點,進行剛纔相同的操做,即:根據爺爺的兄弟顏色作相應的操做。
2.叔叔爲黑
此時較爲複雜,分以下四種狀況:
a)爸爸在左、叔叔在右、我在左

以爸爸爲根節點,進行一次R旋轉。 
b)爸爸在左、叔叔在右、我在右

先以我爲根節點,進行一次L旋轉;
再以我爲根節點,進行一次R旋轉。
c)叔叔在左、爸爸在右、我在左

先以我爲根節點,進行一次R旋轉;
再以我爲根節點,進行一次L旋轉
d)叔叔在左、爸爸在右、我在右

以爸爸爲根節點,進行一次L旋轉。

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

  • 問題1:鏈式二叉查找樹中findMax方法運行時出現空指針異常
    運行截圖以下:

方法代碼及報錯位置截圖以下:

  • 問題1解決方案:通過debug調試發現是邏輯錯誤問題,經過與findMin方法對比改正後代碼以下:
//返回二叉查找樹中的最大元素
    @Override
    public T findMax() {
        T result = null;

        if (isEmpty())
            throw new EmptyCollectionException("LinkedBinarySearchTree");
        else {
            if (root.getRight() == null) {
                result = root.getElement();
            } else {
                BinaryTreeNode<T> current = root.getRight();
                while (current.getRight() != null) {
                    current = current.getRight();
                }
                result = current.getElement();
            }
        }
        return result;
    }
}

代碼託管

上週考試錯題總結

上週無錯題!!!

結對及互評

  • 本週結對學習狀況
    本週主要二叉查找樹進行了較爲深刻的學習,在對鏈式二叉查找樹學習時問題很少,可是當學到了AVL樹時就遇到了較大的麻煩,問題多了起來,可是經過查閱資料以及與結對夥伴的討論,最終使問題獲得了較好的解決,經過結對編程,咱們的學習效率獲得了明顯提高,但願之後更加默契,共同努力,使本身的編程能力獲得更大的提升!

感想

樂觀向上!靈活變通!永不言棄!堅持努力!

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 4/4
第二週 464/464 1/2 10/14 理解掌握了用數組和鏈表實現棧的方法
第三週 494/958 1/3 10/24 理解掌握了用數組和鏈表實現隊列的方法
第四周 1629/2587 2/5 20/44 對用鏈表和數組實現列表進行了學習
第五週 856/3443 2/7 15/59 較爲深刻的學習了查找和排序方法的實現
第六週 668/4111 1/8 20/79 學習了鏈式二叉樹的實現
第七週 900/5011 1/9 15/99 對二叉查找樹進行了較爲深刻的學習
  • 計劃學習時間:20小時

  • 實際學習時間:15小時

  • 改進狀況:在從此的學習中遇到問題,首先要本身努力解決,若是沒有思路,不能一直鑽牛角尖,要學會 查閱資料,吸收別人的經驗,學會揚棄,從而提升本身的學習效率。

參考資料

相關文章
相關標籤/搜索