首先,定義一個樹的高度(如用於AVL樹):
height(leaf) = 1
height(node) = 1 + max(height(node.left), height(node.right))
此外,定義路徑的深度(如用於紅黑樹,一個路徑是從給定節點到某些葉子的後代鏈)是路徑上黑色節點的數量。
正如你指出,關於着色AVL樹作爲紅黑樹的棘手位是確保每個路徑具有相同的深度。您將需要使用AVL不變量:任何給定節點的子樹可以在高度上相差最多一個。
直觀地說,訣竅是使用一種着色算法,其深度對於給定的高度是可預測的,這樣就不需要做任何進一步的全局協調。然後,您可以在本地調整顏色,以確保每個節點的孩子具有相同的深度;這僅僅是因爲AVL條件對其高度差造成嚴格的限制。
此樹着色算法的伎倆:
color_black(x):
x.color = black;
if x is a node:
color_children(x.left, x.right)
color_red(x): // height(x) must be even
x.color = red
color_children(x.left, x.right) // x will always be a node
color_children(a,b):
if height(a) < height(b) or height(a) is odd:
color_black(a)
else:
color_red(a)
if height(b) < height(a) or height(b) is odd:
color_black(b)
else:
color_red(b)
對於AVL樹的根,呼叫color_black(root)
確保灣 請注意,該樹以深度優先順序遍歷,也確保了。
請注意,紅色節點都有高度。樹葉高度爲1,所以它們會被染成黑色,確保c。紅色節點的孩子要麼有奇數的高度,要麼會比他們的兄弟姐妹短,並且將被標記爲黑色,確保d。
最後,顯示e。 (即從根的所有路徑具有相同的深度), 使用感應上n>=1
證明:
- 對於奇數
height = 2*n-1
,
- COLOR_BLACK()創建一個紅黑樹,具有深度
n
- 甚至
height = 2*n
,
- COLOR_RED()將所有的路徑深度
n
- COLOR_BLACK()創建一個紅 - 黑樹深度
n+1
基地情況下,用於n = 1
:
- 對於奇數
height = 1
,樹是葉;
- color_black()將葉子設置爲黑色;唯一的路徑有深度1
- 對於偶數
height = 2
,根是一個節點,並且兩個孩子都是樹葉,如上所示標記爲黑色;
- color_red()將節點設置爲紅色;兩個路徑都具有深度1
- color_black()將節點設置爲黑色;兩個路徑具有深度2
的感應步驟是在這裏我們使用的AVL不變:同級樹可以通過至多1的高度不同。對於具有給定height
一個節點:
- 子情形答:兩個子樹是
(height-1)
- 子情形B:一個子樹是
(height-1)
,並且另一個是(height-2)
感應步驟:給定的假說是對於n
爲真,表明它適用於n+1
:
奇數height = 2*(n+1)-1 = 2*n+1
,
- 子情形答:兩個子樹甚至已經高度
2*n
- color_children()調用COLOR_RED()爲兒童,通過歸納假設
- ,兩個孩子有深入
n
- 父,COLOR_BLACK( )添加黑節點,深度爲
n+1
- 子情況B:子樹有高度
2*n
和2*n-1
- color_children()調用color_red()和color_black(),resp;
- 甚至高度
2*n
,COLOR_RED()產生深度n
(感應HYP。)
- 對於奇數高度
2*n-1
,COLOR_BLACK()產生深度n
(感應HYP。)
- 父,COLOR_BLACK()增加了一個黑色節點,用於深度
n+1
即使height = 2*(n+1) = 2*n + 2
- 子情形答:兩個子樹具有奇數高度
2*n+1 = 2*(n+1)-1
- color_children()爲兩個孩子調用color_black(),深度爲
n+1
- 從奇數高度情況下的上方,兩個孩子具有深度
n+1
- 父,COLOR_RED()增加了一個紅色節點,對於不變深度
n+1
- 父,COLOR_BLACK()增加了一個黑色節點,用於深度
n+2
- 子情形B:子樹有高度
2*n+1 = 2*(n+1)-1
和2*n
- color_children()調用COLOR_BLACK()爲兒童,深度
n+1
- 對於奇數高度
2*n+1
,COLOR_BLACK()產生深度n+1
(見上文)
- 甚至高度
2*n
,COLOR_BLACK()產生深度n+1
(感應HYP。)
- 父,COLOR_RED()增加了一個紅色節點,深度
n+1
- 父,COLOR_BLACK()增加了一個黑色節點,深度
n+2 = (n+1)+1
你在哪裏使用AVL不變? – comingstorm
@comingstorm - OP不需要知道*如何*轉換 –