From 8b401c2acbd11b637fa0d413b64dc5b07c3b8882 Mon Sep 17 00:00:00 2001 From: a16su <33782391+a16su@users.noreply.github.com> Date: Tue, 27 Dec 2022 18:34:12 +0800 Subject: [PATCH] fix format error --- codes/python/chapter_tree/avl_tree.py | 159 +++++--------- .../python/chapter_tree/binary_search_tree.py | 76 +++---- codes/python/chapter_tree/binary_tree.py | 4 +- codes/python/chapter_tree/binary_tree_bfs.py | 21 +- codes/python/chapter_tree/binary_tree_dfs.py | 60 +++--- codes/python/include/binary_tree.py | 16 +- docs/chapter_tree/avl_tree.md | 194 ++++++------------ docs/chapter_tree/binary_search_tree.md | 35 ++-- docs/chapter_tree/binary_tree.md | 46 +++-- 9 files changed, 248 insertions(+), 363 deletions(-) diff --git a/codes/python/chapter_tree/avl_tree.py b/codes/python/chapter_tree/avl_tree.py index 4e6e3572..20cad94b 100644 --- a/codes/python/chapter_tree/avl_tree.py +++ b/codes/python/chapter_tree/avl_tree.py @@ -1,3 +1,9 @@ +""" +File: avl_tree.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + import sys, os.path as osp import typing @@ -5,75 +11,36 @@ sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) from include import * -class AVLTreeNode: - def __init__( - self, - val=None, - height: int = 0, - left: typing.Optional["AVLTreeNode"] = None, - right: typing.Optional["AVLTreeNode"] = None, - ): - self.val = val - self.height = height - self.left = left - self.right = right - - def __str__(self): - val = self.val - left_val = self.left.val if self.left else None - right_val = self.right.val if self.right else None - return "".format( - val, left_val, right_val - ) - - class AVLTree: - def __init__(self, root: typing.Optional[AVLTreeNode] = None): + def __init__(self, root: typing.Optional[TreeNode] = None): self.root = root - @staticmethod - def height(node: typing.Optional[AVLTreeNode]) -> int: - """ - 获取结点高度 - Args: - node:起始结点 + """ 获取结点高度 """ - Returns: 高度 or -1 - - """ + def height(self, node: typing.Optional[TreeNode]) -> int: # 空结点高度为 -1 ,叶结点高度为 0 if node is not None: return node.height return -1 - def __update_height(self, node: AVLTreeNode): - """ - 更新结点高度 - Args: - node: 要更新高度的结点 + """ 更新结点高度 """ - Returns: None - - """ + def __update_height(self, node: TreeNode): # 结点高度等于最高子树高度 + 1 node.height = max([self.height(node.left), self.height(node.right)]) + 1 - def balance_factor(self, node: AVLTreeNode) -> int: - """ - 获取结点平衡因子 - Args: - node: 要获取平衡因子的结点 + """ 获取平衡因子 """ - Returns: 平衡因子 - - """ + def balance_factor(self, node: TreeNode) -> int: # 空结点平衡因子为 0 if node is None: return 0 # 结点平衡因子 = 左子树高度 - 右子树高度 return self.height(node.left) - self.height(node.right) - def __right_rotate(self, node: AVLTreeNode) -> AVLTreeNode: + """ 右旋操作 """ + + def __right_rotate(self, node: TreeNode) -> TreeNode: child = node.left grand_child = child.right # 以 child 为原点,将 node 向右旋转 @@ -85,7 +52,9 @@ class AVLTree: # 返回旋转后子树的根节点 return child - def __left_rotate(self, node: AVLTreeNode) -> AVLTreeNode: + """ 左旋操作 """ + + def __left_rotate(self, node: TreeNode) -> TreeNode: child = node.right grand_child = child.left # 以 child 为原点,将 node 向左旋转 @@ -97,15 +66,9 @@ class AVLTree: # 返回旋转后子树的根节点 return child - def rotate(self, node: AVLTreeNode): - """ - 执行旋转操作,使该子树重新恢复平衡 - Args: - node: 要旋转的根结点 + """ 执行旋转操作,使该子树重新恢复平衡 """ - Returns: 旋转后的根结点 - - """ + def __rotate(self, node: TreeNode) -> TreeNode: # 获取结点 node 的平衡因子 balance_factor = self.balance_factor(node) # 左偏树 @@ -129,76 +92,46 @@ class AVLTree: # 平衡树,无需旋转,直接返回 return node - def insert(self, val) -> AVLTreeNode: - """ - 插入结点 - Args: - val: 结点的值 + """ 插入结点 """ - Returns: - node: 插入结点后的根结点 - """ - self.root = self.insert_helper(self.root, val) + def insert(self, val) -> TreeNode: + self.root = self.__insert_helper(self.root, val) return self.root - def insert_helper( - self, node: typing.Optional[AVLTreeNode], val: int - ) -> AVLTreeNode: - """ - 递归插入结点(辅助函数) - Args: - node: 要插入的根结点 - val: 要插入的结点的值 + """ 递归插入结点(辅助函数)""" - Returns: 插入结点后的根结点 - - """ + def __insert_helper(self, node: typing.Optional[TreeNode], val: int) -> TreeNode: if node is None: - return AVLTreeNode(val) + return TreeNode(val) # 1. 查找插入位置,并插入结点 if val < node.val: - node.left = self.insert_helper(node.left, val) + node.left = self.__insert_helper(node.left, val) elif val > node.val: - node.right = self.insert_helper(node.right, val) + node.right = self.__insert_helper(node.right, val) else: # 重复结点不插入,直接返回 return node # 更新结点高度 self.__update_height(node) # 2. 执行旋转操作,使该子树重新恢复平衡 - return self.rotate(node) + return self.__rotate(node) + + """ 删除结点 """ def remove(self, val: int): - """ - 删除结点 - Args: - val: 要删除的结点的值 - - Returns: - - """ - root = self.remove_helper(self.root, val) + root = self.__remove_helper(self.root, val) return root - def remove_helper( - self, node: typing.Optional[AVLTreeNode], val: int - ) -> typing.Optional[AVLTreeNode]: - """ - 递归删除结点(辅助函数) - Args: - node: 删除的起始结点 - val: 要删除的结点的值 + """ 递归删除结点(辅助函数) """ - Returns: 删除目标结点后的起始结点 - - """ + def __remove_helper(self, node: typing.Optional[TreeNode], val: int) -> typing.Optional[TreeNode]: if node is None: return None # 1. 查找结点,并删除之 if val < node.val: - node.left = self.remove_helper(node.left, val) + node.left = self.__remove_helper(node.left, val) elif val > node.val: - node.right = self.remove_helper(node.right, val) + node.right = self.__remove_helper(node.right, val) else: if node.left is None or node.right is None: child = node.left or node.right @@ -210,17 +143,16 @@ class AVLTree: node = child else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 temp = self.min_node(node.right) - node.right = self.remove_helper(node.right, temp.val) + node.right = self.__remove_helper(node.right, temp.val) node.val = temp.val # 更新结点高度 self.__update_height(node) # 2. 执行旋转操作,使该子树重新恢复平衡 - return self.rotate(node) + return self.__rotate(node) - def min_node( - self, node: typing.Optional[AVLTreeNode] - ) -> typing.Optional[AVLTreeNode]: - # 获取最小结点 + """ 获取最小结点 """ + + def min_node(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if node is None: return None # 循环访问左子结点,直到叶结点时为最小结点,跳出 @@ -228,15 +160,22 @@ class AVLTree: node = node.left return node + """ 查找结点 """ + def search(self, val: int): cur = self.root + # 循环查找,越过叶结点后跳出 while cur is not None: + # 目标结点在 root 的右子树中 if cur.val < val: cur = cur.right + # 目标结点在 root 的左子树中 elif cur.val > val: cur = cur.left + # 找到目标结点,跳出循环 else: break + # 返回目标结点 return cur diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index 211e7c0d..2123252c 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -1,43 +1,46 @@ """ File: binary_search_tree.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) +Created Time: 2022-12-20 +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) -> None: + def __init__(self, nums: typing.List[int]) -> None: nums.sort() - self.__root = self.buildTree(nums, 0, len(nums) - 1) + self.__root = self.build_tree(nums, 0, len(nums) - 1) - def buildTree(self, nums, start_index, end_index): + """ 构建二叉搜索树 """ + + def build_tree(self, nums: typing.List[int], start_index: int, end_index: int) -> typing.Optional[TreeNode]: if start_index > end_index: return None + + # 将数组中间结点作为根结点 mid = (start_index + end_index) // 2 root = TreeNode(nums[mid]) - root.left = self.buildTree( - nums=nums, start_index=start_index, end_index=mid - 1 - ) - root.right = self.buildTree(nums=nums, start_index=mid + 1, end_index=end_index) + # 递归建立左子树和右子树 + root.left = self.build_tree(nums=nums, start_index=start_index, end_index=mid - 1) + root.right = self.build_tree(nums=nums, start_index=mid + 1, end_index=end_index) return root - def get_root(self): + @property + def root(self) -> typing.Optional[TreeNode]: return self.__root - def search(self, num): - """ - 查找结点 - """ - cur = self.get_root() + """ 查找结点 """ + + def search(self, num: int) -> typing.Optional[TreeNode]: + cur = self.root # 循环查找,越过叶结点后跳出 while cur is not None: # 目标结点在 root 的右子树中 @@ -51,11 +54,10 @@ class BinarySearchTree: break return cur - def insert(self, num): - """ - 插入结点 - """ - root = self.get_root() + """ 插入结点 """ + + def insert(self, num: int) -> typing.Optional[TreeNode]: + root = self.root # 若树为空,直接提前返回 if root is None: return None @@ -83,11 +85,10 @@ class BinarySearchTree: pre.left = node return node - def remove(self, num): - """ - 删除结点 - """ - root = self.get_root() + """ 删除结点 """ + + def remove(self, num: int) -> typing.Optional[TreeNode]: + root = self.root # 若树为空,直接提前返回 if root is None: return None @@ -130,10 +131,9 @@ class BinarySearchTree: cur.val = tmp return cur - def min(self, root): - """ - 获取最小结点 - """ + """ 获取最小结点 """ + + def min(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if root is None: return root @@ -148,7 +148,7 @@ if __name__ == "__main__": nums = list(range(1, 16)) bst = BinarySearchTree(nums=nums) print("\n初始化的二叉树为\n") - print_tree(bst.get_root()) + print_tree(bst.root) # 查找结点 node = bst.search(5) @@ -157,17 +157,17 @@ if __name__ == "__main__": # 插入结点 ndoe = bst.insert(16) print("\n插入结点 16 后,二叉树为\n") - print_tree(bst.get_root()) + print_tree(bst.root) # 删除结点 bst.remove(1) print("\n删除结点 1 后,二叉树为\n") - print_tree(bst.get_root()) + print_tree(bst.root) bst.remove(2) print("\n删除结点 2 后,二叉树为\n") - print_tree(bst.get_root()) + print_tree(bst.root) bst.remove(4) print("\n删除结点 4 后,二叉树为\n") - print_tree(bst.get_root()) + print_tree(bst.root) diff --git a/codes/python/chapter_tree/binary_tree.py b/codes/python/chapter_tree/binary_tree.py index 2a892fae..b1d8a13e 100644 --- a/codes/python/chapter_tree/binary_tree.py +++ b/codes/python/chapter_tree/binary_tree.py @@ -1,7 +1,7 @@ """ File: binary_tree.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) """ import sys, os.path as osp diff --git a/codes/python/chapter_tree/binary_tree_bfs.py b/codes/python/chapter_tree/binary_tree_bfs.py index 57d15f91..d7865b6f 100644 --- a/codes/python/chapter_tree/binary_tree_bfs.py +++ b/codes/python/chapter_tree/binary_tree_bfs.py @@ -1,17 +1,22 @@ """ File: binary_tree_bfs.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) +Created Time: 2022-12-20 +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 hierOrder(root): +""" 层序遍历 """ + + +def hier_order(root: TreeNode): # 初始化队列,加入根结点 - queue = collections.deque() + queue: typing.Deque[TreeNode] = collections.deque() queue.append(root) # 初始化一个列表,用于保存遍历序列 result = [] @@ -33,13 +38,11 @@ def hierOrder(root): 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, None, None, None, None, None, None, None, None]) print("\n初始化二叉树\n") print_tree(root) # 层序遍历 - result = hierOrder(root) + result = hier_order(root) print("\n层序遍历的结点打印序列 = ", result) - assert result == [1, 2, 3, 4, 5, 6, 7] \ No newline at end of file + assert result == [1, 2, 3, 4, 5, 6, 7] diff --git a/codes/python/chapter_tree/binary_tree_dfs.py b/codes/python/chapter_tree/binary_tree_dfs.py index 6c5b92a3..31b16055 100644 --- a/codes/python/chapter_tree/binary_tree_dfs.py +++ b/codes/python/chapter_tree/binary_tree_dfs.py @@ -1,10 +1,12 @@ """ File: binary_tree_dfs.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) +Created Time: 2022-12-20 +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 * @@ -12,42 +14,42 @@ from include import * result = [] -def preOrder(root): - """ - 前序遍历二叉树 - """ +""" 前序遍历二叉树 """ + + +def pre_order(root: typing.Optional[TreeNode]): if root is None: return # 访问优先级:根结点 -> 左子树 -> 右子树 result.append(root.val) - preOrder(root=root.left) - preOrder(root=root.right) + pre_order(root=root.left) + pre_order(root=root.right) -def inOrder(root): - """ - 中序遍历二叉树 - """ +""" 中序遍历二叉树 """ + + +def in_order(root: typing.Optional[TreeNode]): if root is None: return # 访问优先级:左子树 -> 根结点 -> 右子树 - inOrder(root=root.left) + in_order(root=root.left) result.append(root.val) - inOrder(root=root.right) + in_order(root=root.right) -def postOrder(root): - """ - 后序遍历二叉树 - """ +""" 后序遍历二叉树 """ + + +def post_order(root: typing.Optional[TreeNode]): if root is None: return # 访问优先级:左子树 -> 右子树 -> 根结点 - postOrder(root=root.left) - postOrder(root=root.right) + post_order(root=root.left) + post_order(root=root.right) result.append(root.val) @@ -55,26 +57,24 @@ def postOrder(root): 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, None, None, None, None, None, None, None, None]) print("\n初始化二叉树\n") print_tree(root) # 前序遍历 - result = [] - preOrder(root) + result.clear() + pre_order(root) print("\n前序遍历的结点打印序列 = ", result) assert result == [1, 2, 4, 5, 3, 6, 7] # 中序遍历 - result = [] - inOrder(root) + result.clear() + in_order(root) print("\n中序遍历的结点打印序列 = ", result) assert result == [4, 2, 5, 1, 6, 3, 7] # 后序遍历 - result = [] - postOrder(root) + result.clear() + post_order(root) print("\n后序遍历的结点打印序列 = ", result) - assert result == [4, 5, 2, 6, 7, 3, 1] \ No newline at end of file + assert result == [4, 5, 2, 6, 7, 3, 1] diff --git a/codes/python/include/binary_tree.py b/codes/python/include/binary_tree.py index bfe5b5f2..fe96f504 100644 --- a/codes/python/include/binary_tree.py +++ b/codes/python/include/binary_tree.py @@ -10,9 +10,19 @@ class TreeNode: """Definition for a binary tree node """ def __init__(self, val=None, left=None, right=None): - self.val = val - self.left = left - self.right = right + self.val = val # 结点值 + self.height = 0 # 结点高度, avl 树会用到 + self.left = left # 左子结点引用 + self.right = right # 右子结点引用 + + def __str__(self): # 直接print时会好看一点 + val = self.val + left_node_val = self.left.val if self.left else None + right_node_val = self.right.val if self.right else None + return "".format(val, left_node_val, right_node_val) + + __repr__ = __str__ + def list_to_tree(arr): """Generate a binary tree with a list diff --git a/docs/chapter_tree/avl_tree.md b/docs/chapter_tree/avl_tree.md index ef88975b..5f2cfb18 100644 --- a/docs/chapter_tree/avl_tree.md +++ b/docs/chapter_tree/avl_tree.md @@ -48,24 +48,21 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "Python" ```python title="avl_tree.py" - class AVLTreeNode: - def __init__( - self, - val=None, - height: int = 0, - left: typing.Optional["AVLTreeNode"] = None, - right: typing.Optional["AVLTreeNode"] = None - ): - self.val = val - self.height = height - self.left = left - self.right = right + """ AVL 树结点类 """ + class TreeNode: + def __init__(self, val=None, left=None, right=None): + self.val = val # 结点值 + self.height = 0 # 结点高度, avl 树会用到 + self.left = left # 左子结点引用 + self.right = right # 右子结点引用 - def __str__(self): + def __str__(self): # 直接print时会好看一点 val = self.val - left_val = self.left.val if self.left else None - right_val = self.right.val if self.right else None - return "".format(val, left_val, right_val) + left_node_val = self.left.val if self.left else None + right_node_val = self.right.val if self.right else None + return "".format(val, left_node_val, right_node_val) + + __repr__ = __str__ ``` === "Go" @@ -125,31 +122,17 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "Python" ```python title="avl_tree.py" - def height(node: typing.Optional[AVLTreeNode]) -> int: - """ - 获取结点高度 - Args: - node:起始结点 - - Returns: 高度 or -1 - - """ + """ 获取结点高度 """ + def height(self, node: typing.Optional[TreeNode]) -> int: # 空结点高度为 -1 ,叶结点高度为 0 if node is not None: return node.height return -1 - def update_height(node: AVLTreeNode): - """ - 更新结点高度 - Args: - node: 要更新高度的结点 - - Returns: None - - """ + """ 更新结点高度 """ + def __update_height(self, node: TreeNode): # 结点高度等于最高子树高度 + 1 - node.height = max([height(node.left), height(node.right)]) + 1 + node.height = max([self.height(node.left), self.height(node.right)]) + 1 ``` === "Go" @@ -207,20 +190,13 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "Python" ```python title="avl_tree.py" - def balance_factor(node: AVLTreeNode) -> int: - """ - 获取结点平衡因子 - Args: - node: 要获取平衡因子的结点 - - Returns: 平衡因子 - - """ + """ 获取平衡因子 """ + def balance_factor(self, node: TreeNode) -> int: # 空结点平衡因子为 0 if node is None: return 0 # 结点平衡因子 = 左子树高度 - 右子树高度 - return height(node.left) - height(node.right) + return self.height(node.left) - self.height(node.right) ``` === "Go" @@ -309,15 +285,16 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - def rightRotate(node: AVLTreeNode): + """ 右旋操作 """ + def __right_rotate(self, node: TreeNode) -> TreeNode: child = node.left grand_child = child.right # 以 child 为原点,将 node 向右旋转 child.right = node node.left = grand_child # 更新结点高度 - update_height(node) - update_height(child) + self.__update_height(node) + self.__update_height(child) # 返回旋转后子树的根节点 return child ``` @@ -387,15 +364,16 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - def leftRotate(node: AVLTreeNode): + """ 左旋操作 """ + def __left_rotate(self, node: TreeNode) -> TreeNode: child = node.right grand_child = child.left # 以 child 为原点,将 node 向左旋转 child.left = node node.right = grand_child # 更新结点高度 - update_height(node) - update_height(child) + self.__update_height(node) + self.__update_height(child) # 返回旋转后子树的根节点 return child ``` @@ -506,35 +484,28 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - def rotate(node: AVLTreeNode): - """ - 执行旋转操作,使该子树重新恢复平衡 - Args: - node: 要旋转的根结点 - - Returns: 旋转后的根结点 - - """ + """ 执行旋转操作,使该子树重新恢复平衡 """ + def __rotate(self, node: TreeNode) -> TreeNode: # 获取结点 node 的平衡因子 - factor = balance_factor(node) + balance_factor = self.balance_factor(node) # 左偏树 - if factor > 1: - if balance_factor(node.left) >= 0: + if balance_factor > 1: + if self.balance_factor(node.left) >= 0: # 右旋 - return right_rotate(node) + return self.__right_rotate(node) else: # 先左旋后右旋 - node.left = left_rotate(node.left) - return right_rotate(node) + node.left = self.__left_rotate(node.left) + return self.__right_rotate(node) # 右偏树 - elif factor < -1: - if balance_factor(node.right) <= 0: + elif balance_factor < -1: + if self.balance_factor(node.right) <= 0: # 左旋 - return left_rotate(node) + return self.__left_rotate(node) else: # 先右旋后左旋 - node.right = right_rotate(node.right) - return left_rotate(node) + node.right = self.__right_rotate(node.right) + return self.__left_rotate(node) # 平衡树,无需旋转,直接返回 return node ``` @@ -611,42 +582,27 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - def insert(val) -> AVLTreeNode: - """ - 插入结点 - Args: - val: 结点的值 + """ 插入结点 """ + def insert(self, val) -> TreeNode: + self.root = self.__insert_helper(self.root, val) + return self.root - Returns: - node: 插入结点后的根结点 - """ - root = insert_helper(root, val) - return root - - def insert_helper(node: typing.Optional[AVLTreeNode], val: int) -> AVLTreeNode: - """ - 递归插入结点(辅助函数) - Args: - node: 要插入的根结点 - val: 要插入的结点的值 - - Returns: 插入结点后的根结点 - - """ + """ 递归插入结点(辅助函数)""" + def __insert_helper(self, node: typing.Optional[TreeNode], val: int) -> TreeNode: if node is None: - return AVLTreeNode(val) + return TreeNode(val) # 1. 查找插入位置,并插入结点 if val < node.val: - node.left = insert_helper(node.left, val) + node.left = self.__insert_helper(node.left, val) elif val > node.val: - node.right = insert_helper(node.right, val) + node.right = self.__insert_helper(node.right, val) else: # 重复结点不插入,直接返回 return node # 更新结点高度 - update_height(node) + self.__update_height(node) # 2. 执行旋转操作,使该子树重新恢复平衡 - return rotate(node) + return self.__rotate(node) ``` === "Go" @@ -743,35 +699,20 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - def remove(val: int): - """ - 删除结点 - Args: - val: 要删除的结点的值 - - Returns: - - """ - root = remove_helper(root, val) + """ 删除结点 """ + def remove(self, val: int): + root = self.__remove_helper(self.root, val) return root - def remove_helper(node: typing.Optional[AVLTreeNode], val: int) -> typing.Optional[AVLTreeNode]: - """ - 递归删除结点(辅助函数) - Args: - node: 删除的起始结点 - val: 要删除的结点的值 - - Returns: 删除目标结点后的起始结点 - - """ + """ 递归删除结点(辅助函数) """ + def __remove_helper(self, node: typing.Optional[TreeNode], val: int) -> typing.Optional[TreeNode]: if node is None: return None # 1. 查找结点,并删除之 if val < node.val: - node.left = remove_helper(node.left, val) + node.left = self.__remove_helper(node.left, val) elif val > node.val: - node.right = remove_helper(node.right, val) + node.right = self.__remove_helper(node.right, val) else: if node.left is None or node.right is None: child = node.left or node.right @@ -781,18 +722,17 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 # 子结点数量 = 1 ,直接删除 node else: node = child - else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - temp = min_node(node.right) - node.right = remove_helper(node.right, temp.val) + else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 + temp = self.min_node(node.right) + node.right = self.__remove_helper(node.right, temp.val) node.val = temp.val # 更新结点高度 - update_height(node) + self.__update_height(node) # 2. 执行旋转操作,使该子树重新恢复平衡 - return rotate(node) + return self.__rotate(node) - - def min_node(node: typing.Optional[AVLTreeNode]) -> typing.Optional[AVLTreeNode]: - # 获取最小结点 + """ 获取最小结点 """ + def min_node(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if node is None: return None # 循环访问左子结点,直到叶结点时为最小结点,跳出 diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index a9328ddc..08d16e4e 100644 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -82,11 +82,9 @@ comments: true === "Python" ```python title="binary_search_tree.py" - def search(self, num): - """ - 查找结点 - """ - cur = self.get_root() + """ 查找结点 """ + def search(self, num: int) -> typing.Optional[TreeNode]: + cur = self.root # 循环查找,越过叶结点后跳出 while cur is not None: # 目标结点在 root 的右子树中 @@ -99,7 +97,6 @@ comments: true else: break return cur - ``` === "Go" @@ -245,11 +242,9 @@ comments: true === "Python" ```python title="binary_search_tree.py" - def insert(self, num): - """ - 插入结点 - """ - root = self.get_root() + """ 插入结点 """ + def insert(self, num: int) -> typing.Optional[TreeNode]: + root = self.root # 若树为空,直接提前返回 if root is None: return None @@ -530,15 +525,13 @@ comments: true === "Python" ```python title="binary_search_tree.py" - def remove(self, num): - """ - 删除结点 - """ - root = self.get_root() + """ 删除结点 """ + def remove(self, num: int) -> typing.Optional[TreeNode]: + root = self.root # 若树为空,直接提前返回 if root is None: return None - + cur = root pre = None @@ -574,13 +567,11 @@ comments: true # 递归删除结点 nex self.remove(nex.val) # 将 nex 的值复制给 cur - cur.val = tmp + cur.val = tmp return cur - def min(self, root): - """ - 获取最小结点 - """ + """ 获取最小结点 """ + def min(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if root is None: return root diff --git a/docs/chapter_tree/binary_tree.md b/docs/chapter_tree/binary_tree.md index ab67e6f8..d1e7774a 100644 --- a/docs/chapter_tree/binary_tree.md +++ b/docs/chapter_tree/binary_tree.md @@ -33,12 +33,19 @@ comments: true === "Python" ```python title="" + """ 链表结点类 """ class TreeNode: - """ 链表结点类 """ def __init__(self, val=None, left=None, right=None): self.val = val # 结点值 self.left = left # 左子结点指针 self.right = right # 右子结点指针 + + def __str__(self): + val = self.val + left_node_val = self.left.val if self.left else None + right_node_val = self.right.val if self.right else None + return "".format(val, left_node_val, right_node_val) + ``` === "Go" @@ -423,7 +430,8 @@ comments: true === "Python" ```python title="binary_tree_bfs.py" - def hierOrder(root): + """ 层序遍历 """ + def hier_order(root): # 初始化队列,加入根结点 queue = collections.deque() queue.append(root) @@ -612,42 +620,36 @@ comments: true === "Python" ```python title="binary_tree_dfs.py" - def preOrder(root): - """ - 前序遍历二叉树 - """ + """ 前序遍历二叉树 """ + def pre_order(root: typing.Optional[TreeNode]): if root is None: return - + # 访问优先级:根结点 -> 左子树 -> 右子树 result.append(root.val) - preOrder(root=root.left) - preOrder(root=root.right) + pre_order(root=root.left) + pre_order(root=root.right) - def inOrder(root): - """ - 中序遍历二叉树 - """ + """ 中序遍历二叉树 """ + def in_order(root: typing.Optional[TreeNode]): if root is None: return # 访问优先级:左子树 -> 根结点 -> 右子树 - inOrder(root=root.left) + in_order(root=root.left) result.append(root.val) - inOrder(root=root.right) + in_order(root=root.right) - def postOrder(root): - """ - 后序遍历二叉树 - """ + """ 后序遍历二叉树 """ + def post_order(root: typing.Optional[TreeNode]): if root is None: return - + # 访问优先级:左子树 -> 右子树 -> 根结点 - postOrder(root=root.left) - postOrder(root=root.right) + post_order(root=root.left) + post_order(root=root.right) result.append(root.val) ```