数据结构之树(二叉排序树)

特点

二叉排序树(Binary Search Tree,BST)的特点:

  1. 每个节点最多有两个子节点,分别称为左子节点和右子节点。
  2. 节点的左子树中的所有节点的值都小于该节点的值。
  3. 节点的右子树中的所有节点的值都大于该节点的值。
  4. 左子树和右子树也分别是二叉排序树。

BST的主要优点是可以实现高效的查找、插入和删除操作,时间复杂度为O(log n),其中n是树中节点的数量。这使得BST成为一种非常有用的数据结构,常被用于搜索、排序和关联数据的存储。

最佳实践

  1. 插入节点:

    • 插入节点时,首先从根节点开始,比较要插入的值和当前节点的值。
    • 如果要插入的值小于当前节点的值,就移动到左子节点;如果大于当前节点的值,就移动到右子节点。
    • 重复这个过程,直到找到一个空的位置,将新节点插入其中。
  2. 删除节点:

    • 删除节点时,首先找到要删除的节点。
    • 如果要删除的节点没有子节点,直接删除它。
    • 如果要删除的节点有一个子节点,将子节点替代被删除的节点。
    • 如果要删除的节点有两个子节点,可以选择用左子树中的最大值节点或右子树中的最小值节点来替代被删除的节点。
  3. 查找节点:

    • 查找节点时,从根节点开始,比较要查找的值和当前节点的值。
    • 如果要查找的值等于当前节点的值,就找到了目标节点。
    • 如果要查找的值小于当前节点的值,就移动到左子节点继续查找;如果大于当前节点的值,就移动到右子节点继续查找。
  4. 遍历树:

    • 中序遍历(In-order traversal)可以用来按升序顺序遍历BST的所有节点。

示例

排序树:

 

删除:20

 

删除50:

 

 

 

class TreeNode:
    def __init__(self, key):
        self.val = key
        self.left = None
        self.right = None


def insert(root, key):
    if root is None:
        return TreeNode(key)
    if key < root.val:
        root.left = insert(root.left, key)
    else:
        root.right = insert(root.right, key)
    return root


def delete(root, key):
    if root is None:
        return root
    if key < root.val:
        root.left = delete(root.left, key)
    elif key > root.val:
        root.right = delete(root.right, key)
    else:
        if root.left is None:
            return root.right
        elif root.right is None:
            return root.left
        # 因为删除的就是当前root节点,因此root节点值就变成了,其右子树最小值
        root.val = minValue(root.right)
        root.right = delete(root.right, root.val)
    return root


def minValue(node):
    current = node
    while current.left is not None:
        current = current.left
    return current.val

# 搜索
def search(root, key):
    if root is None or root.val == key:
        return root
    if root.val < key:
        return search(root.right, key)
    return search(root.left, key)

# 中序遍历
def inorder_traversal(root):
    if root:
        inorder_traversal(root.left)
        print(root.val, end=" ")
        inorder_traversal(root.right)


# 示例用法
root = None
root = insert(root, 50)
print("50 after root的值:{}", root.val)
root = insert(root, 30)
print("30 after root的值:{}", root.val)
root = insert(root, 20)
print("20 after root的值:{}", root.val)
root = insert(root, 40)
print("40 after root的值:{}", root.val)
root = insert(root, 70)
print("70 after root的值:{}", root.val)
root = insert(root, 60)
print("60 after root的值:{}", root.val)
root = insert(root, 80)
print("80 after root的值:{}", root.val)

# 中序遍历
print("Inorder遍历结果:")
inorder_traversal(root)
print("root的值:{}", root.val)

print("\n查找 40:", search(root, 40).val)

root = delete(root, 20)
print("删除 20 后的Inorder遍历结果:")
inorder_traversal(root)
print("root的值:{}", root.val)

root = delete(root, 50)
print("删除 50 后的Inorder遍历结果:")
print("root的值:{}", root.val)
inorder_traversal(root)

输出:

50 after root的值:{} 50
30 after root的值:{} 50
20 after root的值:{} 50
40 after root的值:{} 50
70 after root的值:{} 50
60 after root的值:{} 50
80 after root的值:{} 50
Inorder遍历结果:
20 30 40 50 60 70 80 root的值:{} 50

查找 40: 40
删除 20 后的Inorder遍历结果:
30 40 50 60 70 80 root的值:{} 50
删除 50 后的Inorder遍历结果:
root的值:{} 60
30 40 60 70 80 

  

 

posted @ 2023-11-11 11:43  Allen_Hao  阅读(116)  评论(0)    收藏  举报