Merge branch 'master' into binary_search_tree

This commit is contained in:
Yudong Jin
2023-01-10 13:30:38 +08:00
committed by GitHub
215 changed files with 5618 additions and 1642 deletions

View File

@@ -5,30 +5,28 @@ Author: a16su (lpluls001@gmail.com)
"""
import sys, os.path as osp
import typing
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import *
class AVLTree:
def __init__(self, root: typing.Optional[TreeNode] = None):
def __init__(self, root: Optional[TreeNode] = None):
self.root = root
""" 获取结点高度 """
def height(self, node: typing.Optional[TreeNode]) -> int:
def height(self, node: Optional[TreeNode]) -> int:
# 空结点高度为 -1 ,叶结点高度为 0
if node is not None:
return node.height
return -1
""" 更新结点高度 """
def __update_height(self, node: TreeNode):
def __update_height(self, node: Optional[TreeNode]):
# 结点高度等于最高子树高度 + 1
node.height = max([self.height(node.left), self.height(node.right)]) + 1
""" 获取平衡因子 """
def balance_factor(self, node: TreeNode) -> int:
def balance_factor(self, node: Optional[TreeNode]) -> int:
# 空结点平衡因子为 0
if node is None:
return 0
@@ -36,7 +34,7 @@ class AVLTree:
return self.height(node.left) - self.height(node.right)
""" 右旋操作 """
def __right_rotate(self, node: TreeNode) -> TreeNode:
def __right_rotate(self, node: Optional[TreeNode]) -> TreeNode:
child = node.left
grand_child = child.right
# 以 child 为原点,将 node 向右旋转
@@ -49,7 +47,7 @@ class AVLTree:
return child
""" 左旋操作 """
def __left_rotate(self, node: TreeNode) -> TreeNode:
def __left_rotate(self, node: Optional[TreeNode]) -> TreeNode:
child = node.right
grand_child = child.left
# 以 child 为原点,将 node 向左旋转
@@ -62,7 +60,7 @@ class AVLTree:
return child
""" 执行旋转操作,使该子树重新恢复平衡 """
def __rotate(self, node: TreeNode) -> TreeNode:
def __rotate(self, node: Optional[TreeNode]) -> TreeNode:
# 获取结点 node 的平衡因子
balance_factor = self.balance_factor(node)
# 左偏树
@@ -92,7 +90,7 @@ class AVLTree:
return self.root
""" 递归插入结点(辅助函数)"""
def __insert_helper(self, node: typing.Optional[TreeNode], val: int) -> TreeNode:
def __insert_helper(self, node: Optional[TreeNode], val: int) -> TreeNode:
if node is None:
return TreeNode(val)
# 1. 查找插入位置,并插入结点
@@ -114,7 +112,7 @@ class AVLTree:
return root
""" 递归删除结点(辅助函数) """
def __remove_helper(self, node: typing.Optional[TreeNode], val: int) -> typing.Optional[TreeNode]:
def __remove_helper(self, node: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if node is None:
return None
# 1. 查找结点,并删除之
@@ -132,7 +130,7 @@ class AVLTree:
else:
node = child
else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点
temp = self.__min_node(node.right)
temp = self.__get_inorder_next(node.right)
node.right = self.__remove_helper(node.right, temp.val)
node.val = temp.val
# 更新结点高度
@@ -140,8 +138,8 @@ class AVLTree:
# 2. 执行旋转操作,使该子树重新恢复平衡
return self.__rotate(node)
""" 获取最小结点 """
def __min_node(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]:
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
def __get_inorder_next(self, node: Optional[TreeNode]) -> Optional[TreeNode]:
if node is None:
return None
# 循环访问左子结点,直到叶结点时为最小结点,跳出

View File

@@ -5,20 +5,18 @@ Author: a16su (lpluls001@gmail.com)
"""
import sys, os.path as osp
import typing
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import *
""" 二叉搜索树 """
class BinarySearchTree:
def __init__(self, nums: typing.List[int]) -> None:
def __init__(self, nums: List[int]) -> None:
nums.sort()
self.__root = self.build_tree(nums, 0, len(nums) - 1)
""" 构建二叉搜索树 """
def build_tree(self, nums: typing.List[int], start_index: int, end_index: int) -> typing.Optional[TreeNode]:
def build_tree(self, nums: List[int], start_index: int, end_index: int) -> Optional[TreeNode]:
if start_index > end_index:
return None
@@ -31,11 +29,11 @@ class BinarySearchTree:
return root
@property
def root(self) -> typing.Optional[TreeNode]:
def root(self) -> Optional[TreeNode]:
return self.__root
""" 查找结点 """
def search(self, num: int) -> typing.Optional[TreeNode]:
def search(self, num: int) -> Optional[TreeNode]:
cur = self.root
# 循环查找,越过叶结点后跳出
while cur is not None:
@@ -51,7 +49,7 @@ class BinarySearchTree:
return cur
""" 插入结点 """
def insert(self, num: int) -> typing.Optional[TreeNode]:
def insert(self, num: int) -> Optional[TreeNode]:
root = self.root
# 若树为空,直接提前返回
if root is None:
@@ -81,7 +79,7 @@ class BinarySearchTree:
return node
""" 删除结点 """
def remove(self, num: int) -> typing.Optional[TreeNode]:
def remove(self, num: int) -> Optional[TreeNode]:
root = self.root
# 若树为空,直接提前返回
if root is None:
@@ -117,7 +115,7 @@ class BinarySearchTree:
# 子结点数量 = 2
else:
# 获取中序遍历中 cur 的下一个结点
nex = self.min(cur.right)
nex = self.get_inorder_next(cur.right)
tmp = nex.val
# 递归删除结点 nex
self.remove(nex.val)
@@ -125,11 +123,10 @@ class BinarySearchTree:
cur.val = tmp
return cur
""" 获取最小结点 """
def min(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]:
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
def get_inorder_next(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if root is None:
return root
# 循环访问左子结点,直到叶结点时为最小结点,跳出
while root.left is not None:
root = root.left
@@ -139,7 +136,7 @@ class BinarySearchTree:
""" Driver Code """
if __name__ == "__main__":
# 初始化二叉搜索树
nums = list(range(1, 16))
nums = list(range(1, 16)) # [1, 2, ..., 15]
bst = BinarySearchTree(nums=nums)
print("\n初始化的二叉树为\n")
print_tree(bst.root)

View File

@@ -36,5 +36,5 @@ if __name__ == "__main__":
print_tree(n1)
# 删除结点
n1.left = n2
print("\n删除结点 P 后\n");
print("\n删除结点 P 后\n")
print_tree(n1)

View File

@@ -5,14 +5,12 @@ Author: a16su (lpluls001@gmail.com)
"""
import sys, os.path as osp
import typing
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import *
""" 层序遍历 """
def hier_order(root: TreeNode):
def hier_order(root: Optional[TreeNode]):
# 初始化队列,加入根结点
queue = collections.deque()
queue.append(root)
@@ -32,7 +30,7 @@ def hier_order(root: TreeNode):
if __name__ == "__main__":
# 初始化二叉树
# 这里借助了一个从数组直接生成二叉树的函数
root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7, None, None, None, None, None, None, None, None])
root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7])
print("\n初始化二叉树\n")
print_tree(root)

View File

@@ -5,8 +5,6 @@ Author: a16su (lpluls001@gmail.com)
"""
import sys, os.path as osp
import typing
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import *
@@ -14,7 +12,7 @@ from include import *
res = []
""" 前序遍历 """
def pre_order(root: typing.Optional[TreeNode]):
def pre_order(root: Optional[TreeNode]):
if root is None:
return
# 访问优先级:根结点 -> 左子树 -> 右子树
@@ -23,7 +21,7 @@ def pre_order(root: typing.Optional[TreeNode]):
pre_order(root=root.right)
""" 中序遍历 """
def in_order(root: typing.Optional[TreeNode]):
def in_order(root: Optional[TreeNode]):
if root is None:
return
# 访问优先级:左子树 -> 根结点 -> 右子树
@@ -32,7 +30,7 @@ def in_order(root: typing.Optional[TreeNode]):
in_order(root=root.right)
""" 后序遍历 """
def post_order(root: typing.Optional[TreeNode]):
def post_order(root: Optional[TreeNode]):
if root is None:
return
# 访问优先级:左子树 -> 右子树 -> 根结点
@@ -45,7 +43,7 @@ def post_order(root: typing.Optional[TreeNode]):
if __name__ == "__main__":
# 初始化二叉树
# 这里借助了一个从数组直接生成二叉树的函数
root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7, None, None, None, None, None, None, None, None])
root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7])
print("\n初始化二叉树\n")
print_tree(root)