Python數據結構之二叉樹增、查、刪、修
增加
一層一層添加數據(層序遍歷原則),使用隊列對結點進行存儲,從左向右增加結點,最終可形成完全二叉樹。
def add(self, val):
"""添加樹節點實現完全二叉樹"""
node = Node(val)
if self.root is None:
self.root = node
return
# 使用隊列來實現節點存儲
queue = [self.root]
while queue:
tmp_node = queue.pop(0) # 先進先出
# 左子樹
if tmp_node.left_child is None:
tmp_node.left_child = node
return
else:
queue.append(tmp_node.left_child)
# 右子樹
if tmp_node.right_child is None:
tmp_node.right_child = node
return
else:
queue.append(tmp_node.right_child)
查找
查找當前結點
-
層序查找
def bro_search(self, val): """查找指定數據的父親結點""" if self.root.val == val: # 根節點無父親節點 return self.root # 層序遍歷,尋找節點 queue = [self.root] while queue: tmp_node = queue.pop(0) if tmp_node.left_child and tmp_node.left_child.val == val: return tmp_node.left_child if tmp_node.right_child and tmp_node.right_child.val == val: return tmp_node.right_child # 往下一層進行尋找 if tmp_node.left_child: queue.append(tmp_node.left_child) if tmp_node.right_child: queue.append(tmp_node.right_child) return None
-
前序查找
def pre_search(self, node, val): """先序遍歷""" if node is None: return if node.val == val: return node left_part = self.pre_search(node.left_child, val) # 直接查找到結點,不在繼續遞歸直接退出 if left_part: return left_part right_part = self.pre_search(node.right_child, val) if right_part: return right_part return None
-
中序查找
def in_search(self, node, val): """中序查找""" if node is None: return left_part = self.in_search(node.left_child, val) if left_part: return left_part print("中序!!!") if node.val == val: return node right_part = self.in_search(node.right_child, val) if right_part: return right_part return None
-
後序查找
def post_search(self, node, val): """後序查找""" if node is None: return left_part = self.post_search(node.left_child, val) if left_part: return left_part right_part = self.post_search(node.right_child, val) if right_part: return right_part print("後序!!!") if node.val == val: return node return None
查找結點的父結點
目標:層序遍歷搜索所查找的結點,並把其父結點作爲返回值返回。
def get_parent(self, val):
"""查找指定數據的父親結點"""
if self.root.val == val: # 根節點無父親節點
return None
# 層序遍歷,尋找節點(隊列)
queue = [self.root]
while queue:
tmp_node = queue.pop(0)
if tmp_node.left_child and tmp_node.left_child.val == val:
return tmp_node
if tmp_node.right_child and tmp_node.right_child.val == val:
return tmp_node
# 往下一層進行尋找
if tmp_node.left_child:
queue.append(tmp_node.left_child)
if tmp_node.right_child:
queue.append(tmp_node.right_child)
刪除
刪除結點及其子結點
目標:搜索到所刪除的結點,並且把孩子結點也刪除。
def del_node(self, node, val):
"""刪除節點的同時需要將左右子樹都刪除"""
if node is None:
return
if node.val == val and node == self.root:
self.root = None
self.flag = True
return
# 結點中找的數值,左右結點置空
if node.val == val:
node.left_child = None
node.right_child = None
return node.val
# 遍歷
left_part = self.del_node(node.left_child, val)
if left_part: # 左樹查找有返回值
node.left_child = None # 查找結點置空
self.flag = True
right_part = self.del_node(node.right_child, val)
if right_part: # 右樹查找有返回值
node.left_child = None
self.flag = True
return None
輸出結果(刪除中間結點1):
刪除前樹結構: 0 1 3 7 8 4 9 2 5 6
刪除後樹結構: 0 2 5 6
輸出結果(刪除葉子結點9):
刪除前樹結構: 0 1 3 7 8 4 9 2 5 6
刪除後樹結構: 0 1 3 7 8 4 2 5 6
輸出結果(刪除根結點0):
刪除前樹結構: 0 1 3 7 8 4 9 2 5 6
刪除後樹結構:
輸出結果(刪除根未知結點):
刪除前樹結構: 0 1 3 7 8 4 9 2 5 6
樹中無指定結點!!!
刪除當前結點
目標:只刪除結點,不刪除其孩子結點
def delete(self, val):
"""刪除指定結點"""
if self.root is None:
return False
# 得到刪除結點的父親結點
parent = self.get_parent(val)
if parent:
# 得到刪除結點
del_node = parent.left_child if parent.left_child.val == val else parent.right_child
if del_node.left_child is None:
if parent.left_child.val == val:
parent.left_child = del_node.right_child
else:
parent.right_child = del_node.right_child
del del_node
return True
elif del_node.right_child is None:
if parent.left_child.val == val:
parent.left_child = del_node.left_child
else:
parent.right_child = del_node.left_child
del del_node
return True
else: # 左右樹都不爲空
tmp_pre = del_node
tmp_next = del_node.right_child
if tmp_next.left_child is None:
tmp_pre.right_child = tmp_next.right_child
tmp_next.left_child = del_node.left_child
tmp_next.right_child = del_node.right_child
else:
while tmp_next.left_child: # 尋找左子樹
tmp_pre = tmp_next
tmp_next = tmp_next.left_child
tmp_pre.left_child = tmp_next.right_child
tmp_next.left_child = del_node.left_child
tmp_next.right_child = del_node.right_child
if parent.left_child.val == val:
parent.left_child = tmp_next
else:
parent.right_child = tmp_next
del del_node
return True
else:
return False
參考
Python 實現二叉樹的創建、二叉樹的添加、二叉樹的刪除、二叉樹的修改、二叉樹的查找、二叉樹的的遍歷 最詳細的二叉樹 增 刪 改 查