一,先介紹一些二叉查找樹的概念和性質。
二、下面分別用僞代碼實現上述操作。
inorder-tree-walk(x)
if x != null
then inorder-tree-walk(left[x])
print(x)
inorder-tree-walk(right[x])
tree-search(x, k)
if x == null or k = key[x]
then return x;
if k < key[x]
then return tree-search(left[x], k)
else return tree-search(right[x], k)
時間是樹的高度h=logn
while版本,不用遞歸
while x!= null and k != key[x]
do if(k < key[x])
then x = left[x]
else x = right[x]
return x
tree-minimum(x)
while left[x] != null
do x = left[x]
return x
tree-successor(x)
1 if right[x] != null //如果x有右子樹,則在右子樹中尋找最小值
2 then return tree-minimum(right[x])
3 y = parent[x]
4 while y !=null and x == right[y] //如果沒有右子樹,則其後繼y,是x的父親結點的第一個右子樹
5 do x == y
6 y == parent[y]
7 return y
tree-insert(T, z)
y = null
x = root[T]
while x != null
do y = x
if(key[x] < key[z])
then x = right[x]
else x = left[x]
parent[z] = y
if(y == null) //樹是空的
then root[T] = z
else if key[z] < key[y]
then left[y] = z
else right[y] = z
2,只有左子樹或者只有右子樹。這個是讓z的子樹與其父親結點相連,刪除z即可。
3,既有左子樹又有右子樹。這是先用succeor方法找到要刪除節點z的後繼y,因爲y一定沒有左子樹(因爲y是z的後繼,參看上文關於後繼的定義,所以y是z的右子樹中最小的一個結點,如果y還有左子樹,則y的左子樹中的結點一定比y小!),所以可以刪除y,並讓y的父親結點成爲y的右子樹的父親結點(類似第2中情況),並用y的key代替z的key。
tree-delete(T, z)
if left[z] == null or right[z] == null //如果沒有做孩子節點或者沒有右孩子節點,及至多有一個子樹
then y = z
else y = tree-successor(z) // 如果都有左孩子和右孩子,則找到他的後繼節點
if left[y] != null
then x = left[y]
else x = right[y]
if x != null // 如果只有一個孩子節點
then parent[x] = parent[y] //讓z的子樹x與其父親結點相連,刪除z即可。
if parent[y] == null //如果y沒有父親節點,說明是根節點
then root[T] = x //則使它的孩子節點爲父親節點
else if y == left[parent[y]] //如果y是其父親節點的左子樹,所以可以刪除y,並讓y的父親結點成爲y的右子樹的父親結點
then left[parent[y]] = x
else right[parent[y]] = x
if y != z
then key[z] = key[y] //並用y的key代替z的key。
return y