• 二分搜索树是二叉树
  • 二分搜索树的每个节点的值都大于其左子树上所有节点的值,小于右子树所有节点的值
  • 存储的元素必须有可比较性
  • 每一个子树都是二分搜索树

image.png

添加元素

  1. class Node:
  2. def __init__(self, key=None, value=None, left=None, right=None):
  3. self.key = key
  4. self.value = value
  5. self.left = left
  6. self.right = right
  7. def new(self, key=None, value=None, left=None, right=None):
  8. self.key = key
  9. self.value = value
  10. self.left = left
  11. self.right = right
  12. class BST:
  13. """
  14. 二分搜索树
  15. """
  16. def __init__(self):
  17. # 根节点
  18. self.root = None
  19. # 树的大小
  20. self.count = 0
  21. def size(self):
  22. # 返回树大小
  23. return self.count
  24. def is_empty(self):
  25. # 是否为空树
  26. return self.count == 0
  27. # 添加元素
  28. def insert_r(self, key, value):
  29. # 递归实现
  30. self.root = self.__insert_r(self.root, key=key, value=value)
  31. def __insert_r(self, node: Node, key, value)->Node:
  32. """
  33. 插入元素 不存在重复元素 如果插入的元素存在 替换即可
  34. 递归插入
  35. :param node: 子树的根
  36. :param key: 键
  37. :param value: 值
  38. :return: 当前树
  39. """
  40. if node is None:
  41. # 上一个节点的子树为空 可以进行插入操作 OR Root
  42. self.count += 1
  43. return Node(key=key, value=value)
  44. # 存在该键 替换值
  45. if key == node.key:
  46. node.value = value
  47. elif key < node.key:
  48. # 应该存储在当前节点的左子树分支
  49. node.left = self.__insert_r(node.left, key, value)
  50. else:
  51. # 应该存储在当前节点的右子树分支
  52. node.right = self.__insert_r(node.right, key, value)
  53. # 返回这个节点
  54. return node
  55. def insert(self,key,value):
  56. # 非递归实现
  57. if self.root is None:
  58. # 根节点
  59. self.root = Node(key,value)
  60. else:
  61. # 当前遍历的节点
  62. node = self.root
  63. # 上一个节点
  64. pre = self.root
  65. is_break =False
  66. while (node is not None):
  67. pre = node
  68. if key<node.key:
  69. # 应该插入到左子树
  70. node = node.left
  71. elif key>node.key:
  72. # 应该插入到右子树
  73. node = node.right
  74. else:
  75. # 替换值
  76. node.value = value
  77. is_break = tree
  78. break
  79. if not is_break:
  80. if key<pre.value:
  81. pre.left = Node(key,value)
  82. else:
  83. pre.right = Node(key, value)
  84. # 是否包含该元素
  85. def contain(self, key):
  86. return self.__contain(self.root, key)
  87. def __contain(self, node: Node, key) -> bool:
  88. # 没有节点则直接返回
  89. if node is None:
  90. return False
  91. if key == node.key:
  92. return True
  93. elif key < node.key:
  94. # 在左子树中查找
  95. return self.__contain(node.left, key)
  96. else:
  97. # 在右子树中查找
  98. return self.__contain(node.right, key)
  99. # 查找元素
  100. def search(self, key):
  101. return self.__search(self.root, key)
  102. def __search(self, node: Node, key):
  103. if node is None:
  104. return None
  105. if key == node.key:
  106. return node.value
  107. elif key < node.key:
  108. return self.__search(node.left, key)
  109. else:
  110. return self.__search(node.right, key)

二分搜索树的遍历

深度

image.png

  • 前序遍历

5 3 6 8 4 2

  1. # 前序遍历
  2. def pre_order_r(self):
  3. # 递归实现遍历
  4. self.__pre_order(self.root)
  5. def __pre_order(self, node: Node):
  6. if node is not None:
  7. # 先打印当前节点的值
  8. print(node.key)
  9. # 后遍历左子树的值
  10. self.__pre_order(node.left)
  11. # 再遍历右子树的值
  12. self.__pre_order(node.right)
  13. def pre_order(self):
  14. # 非递归前序遍历
  15. stacks = [self.root]
  16. while len(stacks) >0:
  17. cur_node = stacks.pop()
  18. print(cur_node.value)
  19. if cur_node.right is not None:
  20. stacks.append(cur_node.right)
  21. if cur_node.left is not None:
  22. stacks.append(cur_node.left)
  • 中序遍历

    1. # 中序遍历
    2. def in_order_r(self):
    3. # 递归实现
    4. self.__in_order_r(self.root)
    5. def __in_order_r(self, node: Node):
    6. if node is not None:
    7. self.__in_order_r(node.left)
    8. print(str(node.key) + " ", end="")
    9. self.__in_order_r(node.right)
    10. def in_order(self):
    11. stacks = []
    12. cur_node = self.root
    13. while cur_node is not None or len(stacks) > 0:
    14. if cur_node is not None:
    15. # 如果是有左边
    16. stacks.append(cur_node)
    17. cur_node = cur_node.left
    18. else:
    19. # 左子树为空 出
    20. pop_node = stacks.pop()
    21. print(pop_node.value, end=" ")
    22. cur_node = pop_node.right
  • 后序遍历

    1. # 后序遍历递归
    2. def post_order_r(self):
    3. self.__post_order_r(self.root)
    4. def __post_order_r(self, node: Node):
    5. if node is not None:
    6. self.__post_order_r(node.left)
    7. self.__post_order_r(node.right)
    8. print(node.key, end=" ")

    广度

    1. def level_order(self):
    2. qlist = Queue(maxsize=100)
    3. qlist.put(self.root)
    4. while (not qlist.empty()):
    5. node = qlist.get()
    6. print(node.key)
    7. if node.left is not None:
    8. qlist.put(node.left)
    9. if node.right is not None:
    10. qlist.put(node.right)

    查询以及删除

    1. # 查找最小值 最小值一定在左子树最左面
    2. def mininum(self):
    3. assert self.count > 0, "tree mast has value"
    4. mininode = self.__mininum(self.root)
    5. return mininode.key
    6. def __mininum(self, node: Node):
    7. if node.left is None:
    8. return node
    9. return self.__mininum(node.left)
    10. # 查找最大值 最大值一定是在右子树最右面
    11. def maxnum(self):
    12. assert self.count > 0, "tree mast has value"
    13. maxinode = self.__maxinum(self.root)
    14. return maxinode.key
    15. def __maxinum(self, node: Node):
    16. if node.right is None:
    17. return node
    18. return self.__maxinum(node.right)
    19. # 删除最小值
    20. def removeMin(self):
    21. if self.root is not None:
    22. self.root = self.__removeMin(self.root)
    23. def __removeMin(self, node: Node):
    24. # 已经是最小值
    25. if node.left is None:
    26. # 可能存在左子树
    27. right_node = node.right
    28. del node
    29. self.count -= 1
    30. return right_node
    31. # 删除后 最小节点的子树肯定是小于当前节点 故放left
    32. node.left = self.__removeMin(node.left)
    33. return node
    34. # 删除最大值
    35. def removeMax(self):
    36. if self.root is not None:
    37. self.root = self.__removeMax(self.root)
    38. def __removeMax(self, node: Node):
    39. # 已经是大小值
    40. if node.right is None:
    41. left_node = node.left
    42. del node
    43. self.count -= 1
    44. return left_node
    45. # 删除后 最大节点的子树肯定是大于当前节点 故放right
    46. node.right = self.__removeMax(node.right)
    47. return node
    48. """
    49. 删除任意节点
    50. 删除左右都有孩子的节点 d
    51. 找到后继即d右节点的最小值(并删除) 代替当前节点d
    52. """
    53. def removeNode(self, key):
    54. self.__removeNode(self.root, key)
    55. def __removeNode(self, node: Node, key):
    56. if node is None:
    57. return None
    58. if key < node.key:
    59. # 继续从左子树中查找
    60. node.left = self.__removeNode(node.left, key)
    61. return node
    62. elif key > node.key:
    63. # 继续从右子树中查找
    64. node.right = self.__removeNode(node.right, key)
    65. return node
    66. else:
    67. # 找到了要删除的点
    68. if node.left is None:
    69. right_node = node.right
    70. del node
    71. self.count -= 1
    72. return right_node
    73. if node.right is None:
    74. left_node = node.left
    75. del node
    76. self.count -= 1
    77. return left_node
    78. # 左右子树都不为空
    79. if node.left is not None and node.right is not None:
    80. # 找到当前节点下二叉树的最小值 要替换到当前位置
    81. minNode = self.__mininum(node.right)
    82. minNode.right = self.__removeMin(node.right)
    83. minNode.left = node.left
    84. del node
    85. self.count -= 1
    86. return minNode

    基于二分搜索树和链表实现集合

    ```python from binary_tree import BST from linked_list import LinkedList

使用二分搜索树实现Set 集合

class SetTree:

  1. # 基于二分搜索树的集合实现
  2. def __init__(self):
  3. self.bst = BST()
  4. def add(self, key, value):
  5. self.bst.insert_r(key,value)
  6. def delete(self, key):
  7. self.bst.removeNode(key)
  8. def get_size(self):
  9. return self.bst.size()
  10. def is_empty(self):
  11. return self.bst.is_empty()
  12. def c(self,key):
  13. return self.bst.contain(key)

class SetLinked:

  1. # 基于链表的集合实现
  2. def __init__(self):
  3. self.list = LinkedList()
  4. def add(self, key):
  5. if not self.contains(key):
  6. self.list.add_first(key)
  7. def delete(self, key):
  8. self.list.remove(key)
  9. def get_size(self):
  10. return self.list.get_size()
  11. def is_empty(self):
  12. return self.list.is_empty()
  13. def contains(self,key):
  14. return self.list.contains(key)

``` 在集合中是没有重复元素的,集合中常见的操作就是添加,删除,查找,其时间复杂度分析如下:

  • 二分搜索树实现的集合

新增O(h) h 表示层数
删除O(h) h 表示层数
查找O(h) h 表示层数
其中h和节点个数的关系(满二叉树为例) h = log2(n+1) 所以整体复杂度为O(log2n)

  • 链表实现集合

新增O(n) 确保元素没有重复,需要在添加之前遍历查找是否存在。
删除O(n)
查找O(n)