BST的形狀爲node
root的parent不存在git
假設元素的插入順序爲30,40,17,20,14 剛開始的時候沒有元素,插入新的元素github
而後插入第二個元素40,它比30要大,置爲它的右節點 插入第三個元素17,比30要小,置爲它的左節點 而後是20,比30小,找到作子樹,左子樹的節點值爲17,再次比較 最後一次元素再次插入,獲得最終的BST結構def insert(self,z):
x = self.root
y=None # x's parent
while x!=None :
//找到要插入的位置
y=x
if x.key <= z.key:
x=x.right
else:
x=x.left
if y == None:
//新插入的元素爲第一個節點
self.root = z
z.parent = None
else:
//接入新的節點
z.parent = y
if y.key <= z.key:
y.right = z
else:
y.left = z
複製代碼
它的耗時爲O(lgn)bash
後繼節點即從值上來說,找到比要找的元素要大最接近的值,根據BST的性質,它確定在右子樹上,因此若是存在存在右子樹,就是右子樹上的最小值,不然回溯到父節點,直到父節點不存在,或者遇到第一個不存在右節點關係的父子節點即獲得後繼值ui
17的後繼是20,即17的右子樹的節點;spa
20的後繼是30,因爲20沒有右子樹,會先回溯到17,而後17是它的父節點的左子樹,那麼它就是後繼節點;指針
40的後繼不存在;code
def successor(self,node):
if node == None:
return None
if node.right != None:
# 後繼必定在node的右節點
return self.minimum(node.right)
y = node.parent
# 後繼節點只能在右節點
while y!=None and node == y.right:
node = y
y=y.parent
return y
複製代碼
最小值則一直遞歸到左子樹沒有節點便可cdn
def minimum(self,node=None):
x = self.root if node == None else node
while x!=None and x.left!=None:
x = x.left
return x
複製代碼
節點刪除以後,必需要維持原有的BST性質blog
def delete(self,node):
if node.left == None:
# 若是node.right 是None 至關於把要刪的節點直接置成None,不然 後繼者必定是第一個right值
return self.transplant(node,node.right)
elif node.right == None:
# node.left 必定存在,只須要替換節點之間的指針
return self.transplant(node,node.left)
else:
# 左子樹和右子樹都有,要維持BST的性質,必須找到後繼節點
successor = self.minimum(node.right)
if successor != node.right:
# 最小的左邊的值必定不存在
self.transplant(successor,successor.right)
# right有變化
successor.right = node.right
# 修改原來節點的父節點 node.right 必定存在
successor.right.parent = successor
self.transplant(node,successor)
successor.left=node.left
# 修改原子節點的父節點 node.left必定存在
successor.left.parent = successor
return node
複製代碼
指針變換關係爲
def transplant(self,d,r):
""" d been delete r replecement"""
if d.parent == None:
self.root = r
elif d == d.parent.left:
d.parent.left = r
else:
d.parent.right = r
if r!=None:
r.parent = d.parent
return d
複製代碼