给定二叉搜索树(BST)和范围[min,max],请删除所有超出给定范围的关键字。修改后的树也应该是BST。例如,考虑以下BST和范围[-10,13]。
给定的树应更改为以下内容。请注意,将删除[-10,13]范围之外的所有键,并且修改后的树为BST。
每个节点有两种可能的情况。
1)节点的密钥不在给定范围内。此案例有两个子案例。
……。 a)节点的密钥小于最小值。
……。 b)节点的密钥大于最大值。
2)节点的密钥在范围内。
对于情况2,我们不需要做任何事情。在情况1中,我们需要删除节点并更改以此节点为根的子树的根。
想法是以后置方式修复树。当我们访问一个节点时,请确保其左子树和右子树已固定。在情况1.a)中,我们只需删除根,然后将正确的子树作为新的根返回。在情况1.b)中,我们删除了根并将左子树作为新的根返回。
以下是上述方法的实现。
C++
// A C++ program to remove BST keys outside the given range
#include
using namespace std;
// A BST node has key, and left and right pointers
struct node
{
int key;
struct node *left;
struct node *right;
};
// Removes all nodes having value outside the given range and returns the root
// of modified tree
node* removeOutsideRange(node *root, int min, int max)
{
// Base Case
if (root == NULL)
return NULL;
// First fix the left and right subtrees of root
root->left = removeOutsideRange(root->left, min, max);
root->right = removeOutsideRange(root->right, min, max);
// Now fix the root. There are 2 possible cases for root
// 1.a) Root's key is smaller than min value (root is not in range)
if (root->key < min)
{
node *rChild = root->right;
delete root;
return rChild;
}
// 1.b) Root's key is greater than max value (root is not in range)
if (root->key > max)
{
node *lChild = root->left;
delete root;
return lChild;
}
// 2. Root is in range
return root;
}
// A utility function to create a new BST node with key as given num
node* newNode(int num)
{
node* temp = new node;
temp->key = num;
temp->left = temp->right = NULL;
return temp;
}
// A utility function to insert a given key to BST
node* insert(node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->key > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;
}
// Utility function to traverse the binary tree after conversion
void inorderTraversal(node* root)
{
if (root)
{
inorderTraversal( root->left );
cout << root->key << " ";
inorderTraversal( root->right );
}
}
// Driver program to test above functions
int main()
{
node* root = NULL;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
cout << "Inorder traversal of the given tree is: ";
inorderTraversal(root);
root = removeOutsideRange(root, -10, 13);
cout << "\nInorder traversal of the modified tree is: ";
inorderTraversal(root);
return 0;
}
Java
// A Java program to remove BST
// keys outside the given range
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
class Node
{
int key;
Node left;
Node right;
}
class GFG
{
// Removes all nodes having value
// outside the given range and
// returns the root of modified tree
private static Node removeOutsideRange(Node root,
int min, int max)
{
// BASE CASE
if(root == null)
{
return null;
}
// FIRST FIX THE LEFT AND
// RIGHT SUBTREE OF ROOT
root.left = removeOutsideRange(root.left,
min, max);
root.right = removeOutsideRange(root.right,
min, max);
// NOW FIX THE ROOT. THERE ARE
// TWO POSSIBLE CASES FOR THE ROOT
// 1. a) Root's key is smaller than
// min value(root is not in range)
if(root.key < min)
{
Node rchild = root.right;
root = null;
return rchild;
}
// 1. b) Root's key is greater than
// max value (Root is not in range)
if(root.key > max)
{
Node lchild = root.left;
root = null;
return lchild;
}
// 2. Root in range
return root;
}
public static Node newNode(int num)
{
Node temp = new Node();
temp.key = num;
temp.left = null;
temp.right = null;
return temp;
}
public static Node insert(Node root,
int key)
{
if(root == null)
{
return newNode(key);
}
if(root.key > key)
{
root.left = insert(root.left, key);
}
else
{
root.right = insert(root.right, key);
}
return root;
}
private static void inorderTraversal(Node root)
{
if(root != null)
{
inorderTraversal(root.left);
System.out.print(root.key + " ");
inorderTraversal(root.right);
}
}
// Driver code
public static void main(String[] args)
{
Node root = null;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
System.out.print("Inorder Traversal of " +
"the given tree is: ");
inorderTraversal(root);
root = removeOutsideRange(root, -10, 13);
System.out.print("\nInorder traversal of " +
"the modified tree: ");
inorderTraversal(root);
}
}
// This code is contributed
// by Divya
Python3
# Python3 program to remove BST keys
# outside the given range
# A BST node has key, and left and right
# pointers. A utility function to create
# a new BST node with key as given num
class newNode:
# Constructor to create a new node
def __init__(self, data):
self.key = data
self.left = None
self.right = None
# Removes all nodes having value outside
# the given range and returns the root
# of modified tree
def removeOutsideRange(root, Min, Max):
# Base Case
if root == None:
return None
# First fix the left and right
# subtrees of root
root.left = removeOutsideRange(root.left,
Min, Max)
root.right = removeOutsideRange(root.right,
Min, Max)
# Now fix the root. There are 2
# possible cases for root
# 1.a) Root's key is smaller than
# min value (root is not in range)
if root.key < Min:
rChild = root.right
return rChild
# 1.b) Root's key is greater than max
# value (root is not in range)
if root.key > Max:
lChild = root.left
return lChild
# 2. Root is in range
return root
# A utility function to insert a given
# key to BST
def insert(root, key):
if root == None:
return newNode(key)
if root.key > key:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
# Utility function to traverse the binary
# tree after conversion
def inorderTraversal(root):
if root:
inorderTraversal( root.left)
print(root.key, end = " ")
inorderTraversal( root.right)
# Driver Code
if __name__ == '__main__':
root = None
root = insert(root, 6)
root = insert(root, -13)
root = insert(root, 14)
root = insert(root, -8)
root = insert(root, 15)
root = insert(root, 13)
root = insert(root, 7)
print("Inorder traversal of the given tree is:",
end = " ")
inorderTraversal(root)
root = removeOutsideRange(root, -10, 13)
print()
print("Inorder traversal of the modified tree is:",
end = " ")
inorderTraversal(root)
# This code is contributed by PranchalK
C#
// A C# program to remove BST
// keys outside the given range
using System;
public class Node
{
public int key;
public Node left;
public Node right;
}
public class GFG
{
// Removes all nodes having value
// outside the given range and
// returns the root of modified tree
private static Node removeOutsideRange(Node root,
int min, int max)
{
// BASE CASE
if(root == null)
{
return null;
}
// FIRST FIX THE LEFT AND
// RIGHT SUBTREE OF ROOT
root.left = removeOutsideRange(root.left,
min, max);
root.right = removeOutsideRange(root.right,
min, max);
// NOW FIX THE ROOT. THERE ARE
// TWO POSSIBLE CASES FOR THE ROOT
// 1. a) Root's key is smaller than
// min value(root is not in range)
if(root.key < min)
{
Node rchild = root.right;
root = null;
return rchild;
}
// 1. b) Root's key is greater than
// max value (Root is not in range)
if(root.key > max)
{
Node lchild = root.left;
root = null;
return lchild;
}
// 2. Root in range
return root;
}
public static Node newNode(int num)
{
Node temp = new Node();
temp.key = num;
temp.left = null;
temp.right = null;
return temp;
}
public static Node insert(Node root,
int key)
{
if(root == null)
{
return newNode(key);
}
if(root.key > key)
{
root.left = insert(root.left, key);
}
else
{
root.right = insert(root.right, key);
}
return root;
}
private static void inorderTraversal(Node root)
{
if(root != null)
{
inorderTraversal(root.left);
Console.Write(root.key + " ");
inorderTraversal(root.right);
}
}
// Driver code
public static void Main(String[] args)
{
Node root = null;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
Console.Write("Inorder Traversal of " +
"the given tree is: ");
inorderTraversal(root);
root = removeOutsideRange(root, -10, 13);
Console.Write("\nInorder traversal of " +
"the modified tree: ");
inorderTraversal(root);
}
}
// This code has been contributed
// by PrinciRaj1992
输出:
Inorder traversal of the given tree is: -13 -8 6 7 13 14 15
Inorder traversal of the modified tree is: -8 6 7 13
时间复杂度: O(n),其中n是给定BST中的节点数。