#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/7/15 0:34
# @Author : @linlianqin
# @Site :
# @File : 二叉查找樹類實現(查找、創建、刪除、插入、遍歷).py
# @Software: PyCharm
# @description:class TreeNode:def __init__(self, val, left=None, right=None):self.val = valself.left = leftself.right = rightclass BST_operation:# 二叉查找數元素查找# 思路:根據二叉查找樹的左小右大的特性,當當前結點值大于target則說明值在左子樹,否則在右子樹def BST_search(self,root, target):# 當訪問到最后得到的是None,說明元素不存在查找樹上if root == None:return False# 當當前結點值等于target時查找成功if root.val == target:return True# 當結點值小于target時,說明目標有可能存在右子樹elif root.val < target:return self.BST_search(root.right, target)# 當結點值小于target時,說明目標有可能存在右子樹if root.val > target:return self.BST_search(root.left, target)# 二叉查找數元素插入# 思路:根據二叉查找樹的左小右大的特性,當當前結點值大于target則說明值插入到,否則在右子樹# 當root == None時,說明就是插入的位置def BST_insert(self,root, target):# 當值為None,創建新結點if root == None:root = TreeNode(target)# 存在時elif root.val == target:passelif root.val < target:root.right = self.BST_insert(root.right, target)elif root.val > target:root.left = self.BST_insert(root.left, target)return root# 二叉查找樹構建# 根據列表進行二叉查找數的建立# 思路:新建一個None結點作為初始頭結點,然后進行后面元素的插入def BST_create(self,li):if len(li) != 0:root = TreeNode(li[0])else:return Nonefor i in range(1, len(li)):self.BST_insert(root, li[i])return root# 二叉查找樹的刪除# 刪除根節點的處理方法,為了保證刪除根節點后依舊是一顆完整的二叉查找樹,這里可以用左子樹中的最大值和右子樹中的最小值來代替根節點,然后在子樹中刪除相應的葉節點# 1)若root值為None,說明二叉樹中不存在要刪除的值# 2)若root值剛好是target,說明已經找到了要刪除的結點,進行刪除處理操作:# a) 如果root沒有左右子樹了,直接刪除結點即可# b)如果root還有左子樹,則尋找左子樹中的最大值,用于替換root,然后在左子樹中刪除結點# c) 如果root還有右子樹,則尋找右子樹的最小樹,用于替換root,然后在右子樹中刪除結點# 3)如果root值大于target,target可能在左子樹,遞歸# 4)如果root值小于target,target可能在右子樹,遞歸## 尋找二叉查找樹以root為根節點的最小權值def BST_search_min(self,root):if root.left:return self.BST_search_min(root.left)else:return root## 尋找二叉查找樹以root為根節點的最大權值def BST_search_max(self,root):if root.right:return self.BST_search_max(root.right)else:return root## 刪除def BST_delete(self,root, target):# todo:這里可選# 1)若root值為None,說明二叉樹中不存在要刪除的值if root.val == None:return# 2)如果root值大于target,target可能在左子樹,遞歸elif root.val > target:root.left = self.BST_delete(root.left, target)# 3)如果root值小于target,target可能在右子樹,遞歸elif root.val < target:root.right = self.BST_delete(root.right, target)# 4)若root值剛好是target,說明已經找到了要刪除的結點,進行刪除處理操作:if root.val == target:# a) 如果root沒有左右子樹了,直接刪除結點即可if root.left is None and root.right is None:root = None# b)如果root還有左子樹,則尋找左子樹中的最大值,用于替換root,然后在左子樹中刪除結點elif root.left is not None:root = root.left# c) 如果root還有右子樹,則尋找右子樹的最小樹,用于替換root,然后在右子樹中刪除結點elif root.right is not None:root = root.rightreturn root# 遍歷二叉查找數,中序遍歷def BST_mid_scan(self,root):if root is None:return# 遍歷左子樹self.BST_mid_scan(root.left)# 遍歷根節點print(root.val, end=',')self.BST_mid_scan(root.right)if __name__ == '__main__':li = [5,3,7,4,2,8,6]print('li:',li)BST = BST_operation()print('構建二叉查找樹--------------------')root = BST.BST_create(li)BST.BST_mid_scan(root)# 插入print("\n插入1--------------------------")BST.BST_insert(root,1)BST.BST_mid_scan(root)# 刪除print("\n刪除6----------------------")BST.BST_delete(root,6)BST.BST_mid_scan(root)# 查找print("\n查找--------------------------------")print("在二叉樹中查找10:",BST.BST_search(root,10))print("在二叉樹中查找5:",BST.BST_search(root,5))
li: [5, 3, 7, 4, 2, 8, 6]
構建二叉查找樹--------------------
2,3,4,5,6,7,8,
插入1--------------------------
1,2,3,4,5,6,7,8,
刪除6----------------------
1,2,3,4,5,7,8,
查找--------------------------------
在二叉樹中查找10: False
在二叉樹中查找5: True
參考:
https://blog.csdn.net/ca___0/article/details/111385872
https://blog.csdn.net/u010089444/article/details/70854510
胡凡——算法筆記