二叉搜索树的删除应该怎么解决

这里是我的代码,只能删掉部分数,我的search函数是如果找的到就返回节点 找不到就返回与她最近似的,所以我的success是在他的右边找与它最相近的,然后删除,不晓得为什么有问题

img

img

img

img

  • 以下回答由chatgpt基于相关博客总结生成:

    首先,在实现二叉搜索树的删除操作时,需要考虑到以下几个方面:

    1. 如果要删除的节点是叶子节点,直接删除即可。

    2. 如果要删除的节点只有一个孩子节点,将孩子节点替代要删除的节点的位置。

    3. 如果要删除的节点有两个孩子节点,需要找到该节点的前驱或后继节点(即当前节点左子树的最大节点或右子树的最小节点),将前驱或后继节点的值复制到当前节点,并删除前驱或后继节点。

    接下来,针对问题中提到的successor操作出现问题的情况,提出以下可能的解决方案:

    1. 在查找后继节点时,除了在当前节点的右子树中查找,也可以在当前节点的左子树中依次查找右子节点,直到找到最小的节点。

    2. 可以考虑使用AVL树或红黑树等平衡二叉搜索树来实现删除操作,这样可以保证树的平衡性,减少删除操作可能出现的问题。

    下面是Python实现二叉搜索树删除操作的代码示例:

    class TreeNode:
        def __init__(self, val):
            self.val = val
            self.left = None
            self.right = None
    
    class BinarySearchTree:
        def __init__(self):
            self.root = None
    
        def insert(self, val):
            if not self.root:
                self.root = TreeNode(val)
                return
    
            cur = self.root
            while True:
                if val < cur.val:
                    if cur.left:
                        cur = cur.left
                    else:
                        cur.left = TreeNode(val)
                        break
                elif val > cur.val:
                    if cur.right:
                        cur = cur.right
                    else:
                        cur.right = TreeNode(val)
                        break
    
        def search(self, val):
            cur = self.root
            while cur:
                if val == cur.val:
                    return cur
                elif val < cur.val:
                    cur = cur.left
                else:
                    cur = cur.right
            return None
    
        def delete(self, val):
            def get_successor(cur):
                # 找到右子树中的最小节点
                succ = cur.right
                while succ and succ.left:
                    succ = succ.left
                return succ
    
            if not self.root:
                return
    
            # 找到要删除的节点以及其父节点
            cur, parent = self.root, None
            while cur and cur.val != val:
                parent = cur
                if val < cur.val:
                    cur = cur.left
                else:
                    cur = cur.right
            if not cur:
                return
    
            if cur.left and cur.right:  # 有两个孩子节点
                succ = get_successor(cur)
                cur.val = succ.val
                cur = succ
                parent = parent.right  # 注意更新父节点为被删除的节点的右孩子节点
            # 删除节点以及更新其父节点
            child = cur.left if cur.left else cur.right
            if not parent:
                self.root = child
            elif parent.left == cur:
                parent.left = child
            else:
                parent.right = child
    

    在上述代码中,insert方法用于向树中插入一个节点,search方法用于查找一个节点,delete方法用于删除一个节点。其中,删除节点时,如果要删除的节点有两个孩子节点,则会先获取该节点的后继节点,把后继节点的值赋给当前节点,并以后继节点为要删除的节点,更新其父节点为被删除的节点的右孩子节点,再执行删除操作。如果要删除的节点只有一个孩子节点或者是叶子节点,则直接删除即可。

    参考资料:

    • 《数据结构与算法分析》
    • https://www.geeksforgeeks.org/binary-search-tree-set-2-delete/
    • https://leetcode.com/problems/delete-node-in-a-bst/