在二叉查找樹中添加元素,改過程相似於樹的查找過程,新元素添加爲樹的葉結點,從根開始,沿着每一個結點中元素所肯定的路徑,直到相應地方向上沒有子結點爲止,此時,將新元素添加爲葉結點。html
若是沒有其餘操做,二叉查找樹的樹形由元素的添加順序來決定。java
注:若是輸入是徹底有序的,二叉查找樹就會退化爲一個有序鏈表,削弱了它自己的價值,以下圖所示。git
第三種狀況,若是被刪除結點有兩個子結點,在樹的更低層找到一個合適的結點來代替它。被刪除結點的子結點成爲替代結點的子結點。數據結構
當從二叉查找樹中刪除有兩個子結點的結點是,比較好的辦法是用它的中序後繼來取代它,即在中序遍歷中排在被刪元素以後的那個元素(緊鄰的下一個值)性能
public interface BinarySearchTreeADT<T> extends BinaryTreeADT<T> { public void addElement(T element); //往樹中添加一個元素 public T removeElement(T targetElement); // 從樹中刪除一個元素 public void removeAllOccurrences(T targetElement); // 從樹中刪除所指定元素的任何存在 public T removeMin(); //刪除樹中最小元素 public T removeMax(); // 刪除樹中最大元素 public T findMin(); //返回一個指向樹中最小元素的引用 public T findMax(); //返回一個指向樹中最大元素的引用 }
在平衡二叉樹中進行查找,比在退化的樹中進行查找的效率高不少。在有n個結點的平衡樹中進行查找及添加操做的效率是進行O(log2 n)次比較(最長路徑的長度)。樹越退化,查找及添加操做的時間複雜度越接近O(n),它抵消了使用查找樹帶來的益處。學習
能夠對二叉查找樹進行旋轉以恢復平衡測試
右旋轉3d
1.令根的左子結點變爲新的根 2.令原根結點變爲新的根結點的右子結點 3.令原根的左子結點的右子結點變爲原根結點的新的左子結點
1.令根的右子結點變爲新的根 2.令原根結點變爲新的根結點的左子結點 3.令原根的右子結點的左子結點變爲原根結點的新的右子結點
並不是全部的不平衡狀況均可以用一個單一的旋轉解決,若是不平衡性是由根的右子結點的左子樹的長路徑引起的,則必須先繞那個異常子樹執行一次右旋轉,而後再繞根執行一次左旋轉(右-左旋轉)。若是不平衡是由根的左子結點的右子樹中的長路徑引起,則執行(左-右旋轉)調試
顯然紅黑樹的平衡性能比AVL的略差些,可是通過大量試驗證實,實際上紅黑樹的效率仍是很不錯了,仍能達到O(logN)code
結點的兄弟結點爲黑色,同時兄弟結點的右子結點爲紅色,左子結點爲紅色;
刪除操做中真正被刪除的一定是隻有一個紅色孩子或沒有孩子的結點。
若是真正的刪除點是一個紅色結點,那麼它一定是一個葉子結點。
在完成pp11.3的時候,一切都很順利,可是在測試的時候報錯了,而後不斷追溯,發現是二叉查找樹繼承的以前的二叉樹的tostring方法有問題,這就很是難受了,又亂七八糟改了半天才能夠
沒有測試
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | |
---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 |
第一週 | 0/0 | 1/1 | 8/8 |
第二週 | 671/671 | 1/2 | 17/25 |
第三週 | 345/1016 | 1/3 | 15/40 |
第四周 | 405/1421 | 2/5 | 23/63 |
第五週 | 1202/2623 | 1/5 | 20/83 |
第六週 | 1741/4364 | 1/6 | 20/103 |
第七週 | 400/4764 | 1/7 | 20/123 |