Python數據結構之搜索二叉樹(BST)
二叉搜索樹也稱二叉排序樹或二叉查找樹。二叉搜索樹:一個二叉樹,可以爲空;如果不爲空,滿足一下性質(整體到部分遵循左小右大原則)。
- 非空左子樹的所有鍵值小於其根結點的鍵值。
- 非空右子樹的所有鍵值大於其根結點的鍵值。
- 左、右子樹都是二叉搜索樹。
BST插入
遵循左子樹的值小於右子樹的值原則進行插入操作
def insert(self, node, val):
"""插入元素(遞歸)"""
if node is None:
node = TreeNode(val)
node.left = node.right = None
else:
# 遞歸左右結點實現,並返回值進行構建樹
if val < node.val:
node.left = self.insert(node.left, val)
elif val > node.val:
node.right = self.insert(node.right, val)
return node
BST查找
BST查找指定元素
- 遞歸方式
def find(self, node, val):
"""查找結點(遞歸)"""
if node is None:
return
if val < node.val:
return self.find(node.left, val)
elif val > node.val:
return self.find(node.right, val)
return node
- 迭代方式
def iter_find(node, val):
"""查找結點(迭代)"""
while node:
if val > node.val:
node = node.right
elif val < node.val:
node = node.left
else: # node.val == val
return node
return None
BST查找最大值和最小值
- 圖示
- 查找最大值(最大值應位於樹的最右面,其可能有左孩子或無孩子結點)
def find_min(self, node):
"""找出最小的值(遞歸)"""
if node is None: # 空BST
return
elif node.left is None:
return node
else:
return self.find_min(node.left)
- 查找最小值(最小值應位於樹的最左面,其可能有右孩子或無孩子結點)
def find_max(node):
"""找出最大值(迭代)"""
if node:
while node.right: # 遍歷最右邊的結點
node = node.right
return node
BST刪除
二叉樹的刪除需要考慮以下三種情況
1)要刪除的是是葉結點:直接刪除,並修改其父結點指向爲空
2)要刪除的結點只有一個孩子結點:將其父結點指向刪除及結點的孩子結點。
3)要刪除的結點有左右兩棵子樹:用另一個結點替代被刪除的結點:右子樹的最小元素或者左子樹的最大元素。
def del_node(self, node, val):
"""刪除結點"""
if node is None:
print("刪除元素暫未找到")
# 1.找刪除結點
elif val < node.val:
node.left = self.del_node(node.left, val) # 與刪除後的新的結點進行連接
elif val > node.val:
node.right = self.del_node(node.right, val)
else:
# 2.刪除結點有左右子樹
if node.left and node.right:
tmp = self.find_min(node.right) # 找尋右子樹的最小結點值
node.val = tmp.val # 把結點元素的置換
node.right = self.del_node(node.right, node.val)
else:
tmp = node
# 3.刪除結點有一個孩子結點或無孩子子結點
if node.left is None: # 有右孩子或無子結點
node = node.right
elif node.right is None: # 有左孩子或無子節點
node = node.left
del tmp
return node
BST測試
實例圖:
執行上述操作結果
BST先序遍歷: 7 3 1 2 5 10 9 12
BST最小結點值: 1
BST最大結點值: 12
BST測試刪除操作
****************************************
BST刪除結點(右左右孩子): 9 3 1 2 5 10 12
BST刪除結點(有一個子孩子): 9 3 2 5 10 12
BST刪除結點(無子孩子): 9 3 2 5 10
****************************************
BST重新插入結點(7): 9 3 2 5 7 10
參考
數據結構與算法–二叉排序樹/二叉查找樹/二叉搜索樹 Python實現二叉排序樹/二叉查找樹/二叉搜索樹的遍歷、查找、刪除 Python最簡單的方式實現二叉排序樹