1:概念
二叉搜尋樹也叫二叉排序樹,它支援的操作有:search, minimum, maximum, predecessor, successor, insert, delete。所以,一顆二叉搜尋樹既可以作為乙個字典,又可以作為乙個優先佇列。
二叉搜尋樹的基本操作時間與這棵樹的高度成正比。二叉搜尋樹的高度可以從
ө(lgn)
到ө(n)
。二叉搜尋樹可以用鍊錶來儲存,每個節點包括:key,衛星資料,left, right, p指標。
二叉搜尋樹的性質是:設x為二叉查詢樹中的乙個節點,如果y是x的左子樹中的乙個節點,則y.key <= x.key;如果y是x的右子樹中的乙個節點,則y.key >= x.key。這個性質對樹中的每個節點都成立。對於一組值,可以用不同的二叉搜尋樹表示。如下圖:
二:按序輸出
中序遍歷二叉搜尋樹,就可以將樹中的元素按序輸出。中序遍歷的時間是:
ө(n)
。三:查詢操作
二叉搜尋樹除了支援search操作之外,還支援minimum, maximum, successor, predecessor的查詢操作。這些操作都可以在o(h)時間內完成,h為二叉搜尋樹的高度
1:search
遞迴演算法:
tree-search(x, k)
if x == null or k == x.key
return x
if k < x.key
return tree-search(x.left, k)
else
return tree-search(x.right, k)
迭代演算法:對於大多數計算機來說,迭代版本的效率要高
iterative-tree-search(x, k)
while x != null and k != x.key
if k < x.key
x = x.left
else x = x.right
return x
2:maximum, minimum
找最小元素,就是從樹根開始,一直沿著左子樹向下尋找,直到找到乙個節點,它沒有左孩子。
找最大元素,就是從樹根開始,一直沿著右子樹向下尋找,直到找到乙個節點,它沒有右孩子。
tree-minimum(x)
while x.left != null
x= x.left
return x
tree-maximum(x)
while x.right != null
x=x. right
return x3:
successor, predecessor
給定乙個二叉搜尋樹中的乙個節點,有時候需要按中序遍歷的次序查詢它的後繼或者前驅。節點x
的後繼就是大於
x.key
的最小關鍵字的節點。如果
x的右子樹非空,則
x的後繼就是
x的右子樹中的最小節點。如果
x的右子樹為空,則需要從
x開始向上尋找,直到找到
x的乙個祖先,他有左孩子。這個祖先就是
x的後繼。
tree-successor(x)
if x.right != null
return tree-minimum(x.right)
y= x.p
while y != null and x==y.right
x = y
y = y.p
return y
如果節點中不含有p指標的話,則是:
tree-successor2(t, x)
if x.right != null
return tree-minimum(x.right)
y = t.root
cur = null
while y != null and x.key != y.key
if x.key < y.key
cur = y
y = y.left
else
y = y.right
return cur節點x
的前驅就是小於
x.key
的最大關鍵字的節點。如果
x的左子樹非空,則
x的後繼就是
x的左子樹中的最大節點。如果
x的左子樹為空,則需要從
x開始向上尋找,直到找到
x的乙個祖先,他有右孩子。這個祖先就是
x的前驅。
tree-predecessor(x)
if x.left != null
return tree-maximum(x.left)
y= x.p
while y != null and x== y.left
x = y
y = y.p
return y
如果節點中不含有p指標的話,則是:
tree- predecessor (t,x)
if x.left != null
return tree- maximum (x. left)
y = t.root
cur = null
while y != null and x.key != y.key
if x.key > y.key
cur = y
y = y. right
else
y = y.left
return cur
四:插入和刪除
插入和刪除操作都會改變二叉搜尋樹,但是同時要保證二叉搜尋樹的性質
插入和刪除操作的執行時間為o(h),h為二叉搜尋樹的高度
1:插入
要插入的新節點都將成為乙個葉子節點,插入操作較簡單,**如下:
tree-insert(t, z)
y = null
x = t.root
while x != null
y= x
if z.key < x.key
x= x.left
else x = x.right
z.p = y
if y == null
t.root = z
else if z.key < y.key
y.left = x
else
y.right = x
2:刪除
刪除操作較複雜,需要區分不同的情況:
a:如果
z沒有孩子節點,則簡單的將
z刪除即可
b:如果
z有乙個孩子節點,則將孩子節點提公升到
z的位置上即可
c:如果
z有兩個孩子,那麼需要找到
z的後繼y,
y一定在
z的右子樹中。如果y是
z的右孩子,那麼
y一定沒有左孩子(參見後繼演算法),此時用y替換
z即可;如果y不是
z的右孩子,則需要用
y的右孩子替換
y,然後用y替換
z。如下圖:
為了在二叉搜尋樹中移動子樹,定義子過程transplant,它用一顆子樹替換另一顆子樹:
transplant(t,u,v) //用v替換u
if u.p == null
t.root = v
else if u == u.p.left
u.p.left = v
else u.p.right = v
if v != null
v.p = u.p
該過程只是使
u的雙親成為
v的雙親,並沒有處理
v的孩子節點的更新,這需要呼叫者來處理:
tree-delete(t, z)
if z.left == null
transplant(t, z, z.right)
else if z.right == null
transplant(t, z, z.left)
else y = tree-minimum(z.right)
if y.p != z
transplant(t, y, y.right)
y.right = z.right
y.right.p = y
transplant(t, z, y)
y.left = z.left
y.left.p = y
五:隨機構建二叉搜尋樹
二叉搜尋樹的操作都能在o(h)時間內完成,h是二叉搜尋樹的高度。在構建二叉搜尋樹的時候,如果
n個關鍵字是按照遞增的順序插入的話,那麼這個樹的高度為
n-1。這是最壞的情況,所以可以對n個關鍵字進行隨機化:隨機構建二叉搜尋樹為按隨機次序插入關鍵字到一顆初始空樹,這裡輸入關鍵字排列共有n!種,每個個排列都是等可能的。
一顆有n
個不同關鍵字的隨機構件二叉搜尋樹的期望高度為
o(lg n)
演算法導論筆記 12二叉搜尋樹
1 概念 二叉搜尋樹也叫二叉排序樹,它支援的操作有 search,minimum,maximum,predecessor,successor,insert,delete。所以,一顆二叉搜尋樹既可以作為乙個字典,又可以作為乙個優先佇列。二叉搜尋樹的基本操作時間與這棵樹的高度成正比。二叉搜尋樹的高度可以...
演算法導論 12章 二叉搜尋樹
最壞執行時間 完全二叉樹 o lgn 線性鏈 o n 隨機構造 o lgn 平均時間o lgn 二叉搜尋樹性質 左子樹小於雙親,右子樹大於雙親 二叉搜尋樹的基本操作所花費的時間與這棵樹的高度成正比。遍歷中序遍歷o n 子樹根在左右之間 偽 inorder tree walk x if x nil i...
演算法導論讀書筆記(12)二叉搜尋樹
第三部分 資料結構 設x是二叉搜尋樹中的乙個結點,則 1.若y是x的左子樹中的乙個結點,那麼 y.key x.key 2.若y是x的右子樹中的乙個結點,那麼 y.key x.key 中序遍歷 輸出的子樹根的關鍵字位於其左子樹的關鍵字和右子樹的關鍵字值之間 先序遍歷 輸出的根的關鍵字在其左右子樹的關鍵...