欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過java.util.TreeMap源碼加強紅黑樹的理解

 更新時間:2017年11月20日 10:34:17   投稿:laozhang  
通過分析java.util.TreeMap源碼來對經(jīng)典問題紅黑樹加強理解和理清思路。

在此之前,腳本之家已經(jīng)為大家整理了很多關(guān)于經(jīng)典問題紅黑樹的思路和解決辦法。本篇文章,是通過分析java.util.TreeMap源碼,讓大家通過實例來對紅黑樹這個問題有更加深入的理解。

本篇將結(jié)合JDK1.6的TreeMap源碼,來一起探索紅-黑樹的奧秘。紅黑樹是解決二叉搜索樹的非平衡問題。

當插入(或者刪除)一個新節(jié)點時,為了使樹保持平衡,必須遵循一定的規(guī)則,這個規(guī)則就是紅-黑規(guī)則: 
1) 每個節(jié)點不是紅色的就是黑色的 
2) 根總是黑色的 
3) 如果節(jié)點是紅色的,則它的子節(jié)點必須是黑色的(反之倒不一定必須為真) 
4) 從跟到葉節(jié)點或者空子節(jié)點的每條路徑,必須包含相同數(shù)目的黑色節(jié)點

插入一個新節(jié)點

紅-黑樹的插入過程和普通的二叉搜索樹基本一致:從跟朝插入點位置走,在每個節(jié)點處通過比較節(jié)點的關(guān)鍵字相對大小來決定向左走還是向右走。

public V put(K key, V value) {
Entry<K,V> t = root;
int cmp;
Entry<K,V> parent;
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0) {
t = t.left;
} else if (cmp > 0) {
t = t.right; 
} else {
// 注意,return退出方法 
return t.setValue(value); 
}
} while (t != null);
Entry<K,V> e = new Entry<K,V>(key, value, parent);
if (cmp < 0) {
parent.left = e;
} else {
parent.right = e;
}
fixAfterInsertion(e);
size++;
modCount++;
return null;
}

但是,在紅-黑樹種,找到插入點更復雜,因為有顏色變換和旋轉(zhuǎn)。fixAfterInsertion()方法就是處理顏色變換和旋轉(zhuǎn),需重點掌握它是如何保持樹的平衡(use rotations and the color rules to maintain the tree's balance)。

下面的討論中,使用X、P、G表示關(guān)聯(lián)的節(jié)點。X表示一個特殊的節(jié)點, P是X的父,G是P的父。

X is a node that has caused a rule violation. (Sometimes X refers to a newly inserted node, and sometimes to the child node when a parent and child have a redred conflict.)

On the way down the tree to find the insertion point, you perform a color flip whenever you find a black node with two red children (a violation of Rule 2). Sometimes the flip causes a red-red conflict (a violation of Rule 3). Call the red child X and the red parent P. The conflict can be fixed with a single rotation or a double rotation, depending on whether X is an outside or inside grandchild of G. Following color flips and rotations, you continue down to the insertion point and insert the new node.

After you've inserted the new node X, if P is black, you simply attach the new red node. If P is red, there are two possibilities: X can be an outside or inside grandchild of G. If X is an outside grandchild, you perform one rotation, and if it's an inside grandchild, you perform two. This restores the tree to a balanced state.

按照上面的解釋,討論可分為3個部分,按復雜程度排列,分別是: 
1) 在下行路途中的顏色變換(Color flips on the way down) 
2) 插入節(jié)點之后的旋轉(zhuǎn)(Rotations after the node is inserted) 
3) 在向下路途上的旋轉(zhuǎn)(Rotations on the way down)

在下行路途中的顏色變換(Color flips on the way down)

Here's the rule: Every time the insertion routine encounters a black node that has two red children, it must change the children to black and the parent to red (unless the parent is the root, which always remains black)

The flip leaves unchanged the number of black nodes on the path from the root on down through P to the leaf or null nodes.

盡管顏色變換不會違背規(guī)則4,但是可能會違背規(guī)則3。如果P的父是黑色的,則P由黑色變成紅色時不會有任何問題,但是,如果P的父是紅色的,那么在P的顏色變化之后,就有兩個紅色節(jié)點相連接了。這個問題需要在繼續(xù)向下沿著路徑插入新節(jié)點之前解決,可以通過旋轉(zhuǎn)修正這個問題,下文將會看到。

插入節(jié)點之后的旋轉(zhuǎn)(Rotations after the node is inserted)

新節(jié)點在插入之前,樹是符合紅-黑規(guī)則,在插入新節(jié)點之后,樹就不平衡了,此時需要通過旋轉(zhuǎn)來調(diào)整樹的平衡,使之重新符合紅-黑規(guī)則。

可能性1:P是黑色的,就什么事情也不用做。插入即可。

可能性2:P是紅色,X是G的一個外側(cè)子孫節(jié)點,則需要一次旋轉(zhuǎn)和一些顏色的變化。 
以插入50,25,75,12,6為例,注意節(jié)點6是一個外側(cè)子孫節(jié)點,它和它的父節(jié)點都是紅色。 

在這個例子中,X是一個外側(cè)子孫節(jié)點而且是左子節(jié)點,X是外側(cè)子孫節(jié)點且為右子節(jié)點,是一種與此對稱的情況。通過用50,25,75,87,93創(chuàng)建樹,同理再畫一畫圖,這里就省略了。

可能性3:P是紅色,X是G的一個內(nèi)側(cè)子孫節(jié)點,則需要兩次旋轉(zhuǎn)和一些顏色的改變。 
以插入50,25,75,12,18為例,注意節(jié)點18是一個內(nèi)側(cè)子孫節(jié)點,它和它的父節(jié)點都是紅色。 

在向下路途上的旋轉(zhuǎn)(Rotations on the way down)

在插入新節(jié)點之前,實際上樹已經(jīng)違背了紅-黑規(guī)則,所以需要插入新節(jié)點之前做調(diào)整。所以我們本次討論的主題是“在向下路途準備插入新節(jié)點時,上面先進行調(diào)整,使上面成為標準的紅黑樹后,再進行新節(jié)點插入”。

外側(cè)子孫節(jié)點

以插入50,25,75,12,37,6,18,3為例,例子中違背規(guī)則的節(jié)點是一個外側(cè)子孫節(jié)點。 

內(nèi)側(cè)子孫節(jié)點

以插入50,25,75,12,37,31,43為例,例子中違背規(guī)則的節(jié)點是一個內(nèi)側(cè)子孫節(jié)點。

紅-黑樹的效率

和一般的二叉搜索樹類似,紅-黑樹的查找、插入和刪除的時間復雜度為O(log2N)。

紅-黑樹的查找時間和普通的二叉搜索樹的查找時間應該幾乎完全一樣。因為在查找過程中并沒用到紅-黑特征。額外的開銷只是每個節(jié)點的存儲空間都稍微增加了一點,來存儲紅黑顏色(一個boolean變量)。

final Entry<K, V> getEntry(Object key) {
Comparable <? super K > k = (Comparable <? super K > ) key;
Entry<K, V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0) {
p = p.left;
} else if (cmp > 0) {
p = p.right;
} else {
return p;
}
}
return null;
}

插入和刪除的時間要增加一個常數(shù)因子,因為不得不在下行的路徑上和插入點執(zhí)行顏色變換和旋轉(zhuǎn)。平均起來一次插入大約需要一次旋轉(zhuǎn)。

因為在大多數(shù)應用中,查找的次數(shù)比插入和刪除的次數(shù)多,所以應用紅-黑樹取代普通的二叉搜索樹總體上不會增加太多的時間開銷。

相關(guān)文章

  • MyBatisPlus代碼生成器的原理及實現(xiàn)詳解

    MyBatisPlus代碼生成器的原理及實現(xiàn)詳解

    這篇文章主要為大家詳細介紹了MyBatisPlus中代碼生成器的原理及實現(xiàn),文中的示例代碼講解詳細,對我們學習MyBatisPlus有一定幫助,需要的可以參考一下
    2022-08-08
  • Java中Steam流的用法詳解

    Java中Steam流的用法詳解

    Stream是Java?8?API添加的一個新的抽象,稱為流Stream,本文主要介紹了Java中Steam流的用法詳解,具有一定的參考價值,感興趣的可以了解一下
    2023-04-04
  • spring定時任務(scheduler)的串行、并行執(zhí)行實現(xiàn)解析

    spring定時任務(scheduler)的串行、并行執(zhí)行實現(xiàn)解析

    這篇文章主要介紹了spring定時任務(scheduler)的串行、并行執(zhí)行實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • jsp中存取session值簡單介紹

    jsp中存取session值簡單介紹

    這篇文章主要介紹了jsp中存取session值簡單介紹,涉及request和session的域操作等相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • java如何判斷一個對象是否為空對象

    java如何判斷一個對象是否為空對象

    本文主要介紹了java如何判斷一個對象是否為空對象,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 使用dubbo+zookeeper+spring boot構(gòu)建服務的方法詳解

    使用dubbo+zookeeper+spring boot構(gòu)建服務的方法詳解

    這篇文章主要給大家介紹了關(guān)于如何使用dubbo+zookeeper+spring boot構(gòu)建服務的相關(guān)資料,文中通過示例代碼及圖片介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-05-05
  • Java中消息隊列任務的平滑關(guān)閉詳解

    Java中消息隊列任務的平滑關(guān)閉詳解

    對于消息隊列的監(jiān)聽,我們一般使用Java寫一個獨立的程序,在Linux服務器上運行。程序啟動后,通過消息隊列客戶端接收消息,放入一個線程池進行異步處理,并發(fā)的快速處理。這篇文章主要給大家介紹了關(guān)于Java中消息隊列任務的平滑關(guān)閉的相關(guān)資料,需要的朋友可以參考下。
    2017-11-11
  • Java解密微信小程序手機號的方法

    Java解密微信小程序手機號的方法

    這篇文章主要為大家詳細介紹了Java解密微信小程序手機號的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • jmeter+ant+jenkins自動化測試環(huán)境配置搭建過程

    jmeter+ant+jenkins自動化測試環(huán)境配置搭建過程

    在搭建jmeter+ant+jenkins環(huán)境有些前提條件,那就是要先配置好java環(huán)境、安裝好jenkins以及配置好jmeter,這樣才能省去很多的事情,對jmeter+ant+jenkins自動化測試環(huán)境配置搭建過程感興趣的朋友一起看看吧
    2021-12-12
  • Java?超詳細講解SpringMVC攔截器

    Java?超詳細講解SpringMVC攔截器

    Spring?MVC?的攔截器(Interceptor)與?Java?Servlet?的過濾器(Filter)類似,它主要用于攔截用戶的請求并做相應的處理,通常應用在權(quán)限驗證、記錄請求信息的日志、判斷用戶是否登錄等功能上。本文將代碼演示和文字描述詳解攔截器的使用
    2022-04-04

最新評論