📜  二叉搜索树 |第 3 组(迭代删除)(1)

📅  最后修改于: 2023-12-03 14:49:01.064000             🧑  作者: Mango

二叉搜索树 | 第 3 组 (迭代删除)

简介

二叉搜索树(BST,Binary Search Tree)是一种特殊的二叉树。它具有以下特点:

  1. 左子树所有节点的值均小于根节点的值。
  2. 右子树所有节点的值均大于根节点的值。
  3. 左右子树也分别是二叉搜索树。

二叉搜索树常用于实现关联数组(即键值对)的数据结构,可以支持快速的插入、查找和删除操作。

本文将介绍二叉搜索树的迭代删除操作。

代码实现
一、删除指定节点

首先,我们需要实现一个函数,用于删除二叉搜索树中指定的节点。

其操作步骤如下:

  1. 如果当前节点为空,则返回空。
  2. 如果待删除的值小于当前节点的值,则递归地在左子树中删除。
  3. 如果待删除的值大于当前节点的值,则递归地在右子树中删除。
  4. 如果待删除的值等于当前节点的值,则进行删除操作。
    1. 如果当前节点没有子节点,则直接删除。
    2. 如果当前节点只有一个子节点,将其子节点替换当前节点。
    3. 如果当前节点有两个子节点,找到其右子树中最小的节点,将其替换当前节点,并删除右子树中的最小节点。
def delete_node(root, val):
    # 如果当前节点为空,则返回空。
    if not root:
        return None
    
    # 如果待删除的值小于当前节点的值,则递归地在左子树中删除。
    if val < root.val:
        root.left = delete_node(root.left, val)
    
    # 如果待删除的值大于当前节点的值,则递归地在右子树中删除。
    elif val > root.val:
        root.right = delete_node(root.right, val)
    
    # 如果待删除的值等于当前节点的值,则进行删除操作。
    else:
        # 如果当前节点没有子节点,则直接删除。
        if not root.left and not root.right:
            root = None
        
        # 如果当前节点只有一个子节点,将其子节点替换当前节点。
        elif not root.left:
            root = root.right
        elif not root.right:
            root = root.left
        
        # 如果当前节点有两个子节点,
        else:
            # 找到其右子树中最小的节点,将其替换当前节点,并删除右子树中的最小节点。
            min_node = root.right
            while min_node.left:
                min_node = min_node.left
            
            root.val = min_node.val
            root.right = delete_node(root.right, min_node.val)
    
    return root
二、迭代删除

实现删除节点的函数之后,我们可以使用循环来迭代地删除二叉搜索树中的节点。

其操作步骤如下:

  1. 如果根节点为空,则返回空。
  2. 如果待删除的值小于当前节点的值,则递归地在左子树中删除。
  3. 如果待删除的值大于当前节点的值,则递归地在右子树中删除。
  4. 如果待删除的值等于当前节点的值,则进行删除操作,并跳出循环。
def delete_iterative(root, val):
    # 如果根节点为空,则返回空。
    if not root:
        return None
    
    node = root
    parent = None
    
    # 查找待删除节点及其父节点。
    while node and node.val != val:
        parent = node
        if val < node.val:
            node = node.left
        else:
            node = node.right
    
    # 如果待删除节点不存在,则返回原根节点。
    if not node:
        return root
    
    # 如果待删除节点存在,则进行删除操作。
    if not node.left and not node.right:
        # 如果待删除的节点没有子节点,则直接删除。
        if not parent:
            root = None
        elif parent.left == node:
            parent.left = None
        else:
            parent.right = None
    
    elif not node.left:
        # 如果待删除的节点只有右子节点,则用右子节点代替待删除节点。
        if not parent:
            root = node.right
        elif parent.left == node:
            parent.left = node.right
        else:
            parent.right = node.right
    
    elif not node.right:
        # 如果待删除的节点只有左子节点,则用左子节点代替待删除节点。
        if not parent:
            root = node.left
        elif parent.left == node:
            parent.left = node.left
        else:
            parent.right = node.left
    
    else:
        # 如果待删除的节点既有左子节点,又有右子节点。
        # 找到待删除节点右子树中的最小节点,将其替换待删除节点,并删除右子树中的最小节点。
        min_node = node.right
        min_parent = node
        while min_node.left:
            min_parent = min_node
            min_node = min_node.left
        
        node.val = min_node.val
        if min_parent.left == min_node:
            min_parent.left = min_node.right
        else:
            min_parent.right = min_node.right
    
    return root
总结

本篇文章介绍了二叉搜索树的迭代删除操作,并给出了相应的代码实现。通过迭代删除,可以快速地删除二叉搜索树中的指定节点,保证二叉搜索树的性质不被破坏。