📜  删除给定范围内的BST键

📅  最后修改于: 2021-05-24 21:27:04             🧑  作者: Mango

给定二分搜索树(BST)和范围[min,max],请删除给定范围内的所有键。修改后的树也应该是BST。例如,考虑以下BST和范围[50,70]。

50
          /     \
         30      70
        /  \    /  \
      20   40  60   80 

The given BST should be transformed to this:
            80
          /
         30
        /  \
      20   40

每个节点有两种可能的情况。
1)节点的密钥在给定范围内。
2)节点的密钥超出范围。

对于情况2,我们不需要做任何事情。在情况1中,我们需要删除节点并更改以此节点为根的子树的根。
想法是以后置方式修复树。当我们访问一个节点时,请确保其左子树和右子树已固定。当我们在范围内找到一个节点时,我们将调用普通的BST删除函数来删除该节点。

以下是上述方法的实现。

C++
// C++ implementation of the above approach
#include 
 
using namespace std;
 
class BSTnode {
public:
    int data;
    BSTnode *left, *right;
    BSTnode(int data)
    {
        this->data = data;
        this->left = this->right = NULL;
    }
};
 
// A Utility function to find leftMost node
BSTnode* leftMost(BSTnode* root)
{
    if (!root)
        return NULL;
    while (root->left)
        root = root->left;
    return root;
}
 
// A Utility function to delete the give node
BSTnode* deleteNode(BSTnode* root)
{
    // node with only one chile or no child
    if (!root->left) {
        BSTnode* child = root->right;
        root = NULL;
        return child;
    }
    else if (!root->right) {
        BSTnode* child = root->left;
        root = NULL;
        return child;
    }
 
    // node with two children: get inorder successor
    // in the right subtree
    BSTnode* next = leftMost(root->right);
 
    // copy the inorder successor's content to this node
    root->data = next->data;
 
    // delete the inorder successor
    root->right = deleteNode(root->right);
 
    return root;
}
 
// function to find node in given range and delete
// it in preorder manner
BSTnode* removeRange(BSTnode* node, int low, int high)
{
 
    // Base case
    if (!node)
        return NULL;
 
    // First fix the left and right subtrees of node
    node->left = removeRange(node->left, low, high);
    node->right = removeRange(node->right, low, high);
 
    // Now fix the node.
    // if given node is in Range then delete it
    if (node->data >= low && node->data <= high)
        return deleteNode(node);
 
    // Root is out of range
    return node;
}
 
// Utility function to traverse the binary tree
// after conversion
void inorder(BSTnode* root)
{
    if (root) {
        inorder(root->left);
        cout << root->data << ' ';
        inorder(root->right);
    }
}
 
// Driver Program to test above functions
int main()
{
    /* Let us create following BST
             50
          /     \
         30      70
        /  \    /  \
      20   40  60   80 */
    BSTnode* root = new BSTnode(50);
    root->left = new BSTnode(30);
    root->right = new BSTnode(70);
    root->left->right = new BSTnode(40);
    root->right->right = new BSTnode(80);
    root->right->left = new BSTnode(60);
    root->left->left = new BSTnode(20);
 
    cout << "Inorder Before deletion: ";
    inorder(root);
 
    root = removeRange(root, 50, 70);
 
    cout << "\nInorder After deletion: ";
    inorder(root);
 
    cout << endl;
    return 0;
}


Java
// Java implementation of the above approach
import java.util.*;
class Solution {
 
    static class BSTnode {
 
        int data;
        BSTnode left, right;
        BSTnode(int data)
        {
            this.data = data;
            this.left = this.right = null;
        }
    }
 
    // A Utility function to find leftMost node
    static BSTnode leftMost(BSTnode root)
    {
        if (root == null)
            return null;
        while (root.left != null)
            root = root.left;
        return root;
    }
 
    // A Utility function to delete the give node
    static BSTnode deleteNode(BSTnode root)
    {
        // node with only one chile or no child
        if (root.left == null) {
            BSTnode child = root.right;
            root = null;
            return child;
        }
        else if (root.right == null) {
            BSTnode child = root.left;
            root = null;
            return child;
        }
 
        // node with two children: get inorder successor
        // in the right subtree
        BSTnode next = leftMost(root.right);
 
        // copy the inorder successor's content to this node
        root.data = next.data;
 
        // delete the inorder successor
        root.right = deleteNode(root.right);
 
        return root;
    }
 
    // function to find node in given range and delete
    // it in preorder manner
    static BSTnode removeRange(BSTnode node, int low, int high)
    {
 
        // Base case
        if (node == null)
            return null;
 
        // First fix the left and right subtrees of node
        node.left = removeRange(node.left, low, high);
        node.right = removeRange(node.right, low, high);
 
        // Now fix the node.
        // if given node is in Range then delete it
        if (node.data >= low && node.data <= high)
            return deleteNode(node);
 
        // Root is out of range
        return node;
    }
 
    // Utility function to traverse the binary tree
    // after conversion
    static void inorder(BSTnode root)
    {
        if (root != null) {
            inorder(root.left);
            System.out.print(root.data + " ");
            inorder(root.right);
        }
    }
 
    // Driver Program to test above functions
    public static void main(String args[])
    {
        /* Let us create following BST
             50
          /     \
         30      70
        /  \    /  \
      20   40  60   80 */
        BSTnode root = new BSTnode(50);
        root.left = new BSTnode(30);
        root.right = new BSTnode(70);
        root.left.right = new BSTnode(40);
        root.right.right = new BSTnode(80);
        root.right.left = new BSTnode(60);
        root.left.left = new BSTnode(20);
 
        System.out.print("Inorder Before deletion: ");
        inorder(root);
 
        root = removeRange(root, 50, 70);
 
        System.out.print("\nInorder After deletion: ");
        inorder(root);
    }
}
// This code is contributed by Arnab Kundu


Python3
# Python3 implementation of the above approach
class BSTnode:
     
    def __init__(self, data):
         
        self.data = data
        self.left = None
        self.right = None
 
# A Utility function to find leftMost node
def leftMost(root):
     
    if (root == None):
        return None
         
    while (root.left):
        root = root.left
         
    return root
 
# A Utility function to delete the give node
def deleteNode(root):
     
    # Node with only one chile or no child
    if (root.left == None):
        child = root.right
        root = None
        return child
         
    elif (root.right == None):
        child = root.left
        root = None
        return child
 
    # Node with two children: get
    # inorder successor in the
    # right subtree
    next = leftMost(root.right)
 
    # Copy the inorder successor's
    # content to this node
    root.data = next.data
     
    # Delete the inorder successor
    root.right = deleteNode(root.right)
 
    return root
 
# Function to find node in given range
# and delete it in preorder manner
def removeRange(node, low, high):
     
    # Base case
    if (node == None):
        return None
 
    # First fix the left and right subtrees of node
    node.left = removeRange(node.left, low, high)
    node.right = removeRange(node.right, low, high)
 
    # Now fix the node. If given node
    # is in Range then delete it
    if (node.data >= low and node.data <= high):
        return deleteNode(node)
 
    # Root is out of range
    return node
 
# Utility function to traverse the
# binary tree after conversion
def inorder(root):
     
    if (root):
        inorder(root.left)
        print(root.data, end = " ")
        inorder(root.right)
 
# Driver code
if __name__ == '__main__':
     
    '''
    Let us create following BST
             50
          /     \
         30      70
        /  /    /  \
      20   40  60   80
    '''
    root = BSTnode(50)
    root.left = BSTnode(30)
    root.right = BSTnode(70)
    root.left.right = BSTnode(40)
    root.right.right = BSTnode(80)
    root.right.left = BSTnode(60)
    root.left.left = BSTnode(20)
 
    print("Inorder Before deletion:", end = "")
    inorder(root)
 
    root = removeRange(root, 50, 70)
 
    print("\nInorder After deletion:", end = "")
    inorder(root)
 
# This code is contributed by bgangwar59


C#
// C# implementation of the above approach
using System;
 
class GFG {
 
    public class BSTnode {
 
        public int data;
        public BSTnode left, right;
        public BSTnode(int data)
        {
            this.data = data;
            this.left = this.right = null;
        }
    }
 
    // A Utility function to find leftMost node
    static BSTnode leftMost(BSTnode root)
    {
        if (root == null)
            return null;
        while (root.left != null)
            root = root.left;
        return root;
    }
 
    // A Utility function to delete the give node
    static BSTnode deleteNode(BSTnode root)
    {
        // node with only one chile or no child
        if (root.left == null) {
            BSTnode child = root.right;
            root = null;
            return child;
        }
        else if (root.right == null) {
            BSTnode child = root.left;
            root = null;
            return child;
        }
 
        // node with two children: get inorder successor
        // in the right subtree
        BSTnode next = leftMost(root.right);
 
        // copy the inorder successor's content to this node
        root.data = next.data;
 
        // delete the inorder successor
        root.right = deleteNode(root.right);
 
        return root;
    }
 
    // function to find node in given range and delete
    // it in preorder manner
    static BSTnode removeRange(BSTnode node, int low, int high)
    {
 
        // Base case
        if (node == null)
            return null;
 
        // First fix the left and right subtrees of node
        node.left = removeRange(node.left, low, high);
        node.right = removeRange(node.right, low, high);
 
        // Now fix the node.
        // if given node is in Range then delete it
        if (node.data >= low && node.data <= high)
            return deleteNode(node);
 
        // Root is out of range
        return node;
    }
 
    // Utility function to traverse the binary tree
    // after conversion
    static void inorder(BSTnode root)
    {
        if (root != null) {
            inorder(root.left);
            Console.Write(root.data + " ");
            inorder(root.right);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        /* Let us create following BST
            50
        /     \
        30     70
        / \ / \
    20 40 60 80 */
        BSTnode root = new BSTnode(50);
        root.left = new BSTnode(30);
        root.right = new BSTnode(70);
        root.left.right = new BSTnode(40);
        root.right.right = new BSTnode(80);
        root.right.left = new BSTnode(60);
        root.left.left = new BSTnode(20);
 
        Console.Write("Inorder Before deletion: ");
        inorder(root);
 
        root = removeRange(root, 50, 70);
 
        Console.Write("\nInorder After deletion: ");
        inorder(root);
    }
}
 
// This code contributed by Rajput-Ji


输出:
Inorder Before deletion: 20 30 40 50 60 70 80 
Inorder After deletion: 20 30 40 80