📌  相关文章
📜  将所有更大的值添加到给定BST中的每个节点

📅  最后修改于: 2021-05-25 00:32:47             🧑  作者: Mango

给定B inary小号Ť操作搜索REE(BST),对其进行修改,使得在给定的BST所有更大的值被添加到每一个节点。例如,考虑以下BST。

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

The above tree should be modified to following 

              260
           /      \
         330        150
        /   \       /  \
      350   300    210   80

解决此问题的一种简单方法是找到每个节点的所有较大值的总和。此方法将花费O(n ^ 2)时间。

本文讨论的方法使用BST的反向有序树遍历技术,该技术优化了单遍历要解决的问题。
方法:在这个问题中,我们可以注意到最大的节点将保持不变。第二大节点的值=第二大节点的值+第二大节点的值。类似地,第n个最大节点的值将是第n个节点与修改后第(n-1)个最大节点的值之和。因此,如果我们以降序遍历树并在将值添加到根节点的同时在每一步同时更新总和值,则将解决该问题。
因此,为了以降序方式遍历BST,我们使用BST的反向顺序遍历。这需要一个全局变量总和,该总和在每个节点上都进行更新,并且一旦到达根节点,就将其添加到根节点的值中,并更新根节点的值。

C++
// C++ program to add all greater
// values in every node of BST
#include 
using namespace std;
  
class Node {
public:
    int data;
    Node *left, *right;
};
  
// A utility function to create
// a new BST node
Node* newNode(int item)
{
    Node* temp = new Node();
    temp->data = item;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Recursive function to add all
// greater values in every node
void modifyBSTUtil(Node* root, int* sum)
{
    // Base Case
    if (root == NULL)
        return;
  
    // Recur for right subtree
    modifyBSTUtil(root->right, sum);
  
    // Now *sum has sum of nodes
    // in right subtree, add
    // root->data to sum and
    // update root->data
    *sum = *sum + root->data;
    root->data = *sum;
  
    // Recur for left subtree
    modifyBSTUtil(root->left, sum);
}
  
// A wrapper over modifyBSTUtil()
void modifyBST(Node* root)
{
    int sum = 0;
    modifyBSTUtil(root, &sum);
}
  
// A utility function to do
// inorder traversal of BST
void inorder(Node* root)
{
    if (root != NULL) {
        inorder(root->left);
        cout << root->data << " ";
        inorder(root->right);
    }
}
  
/* A utility function to insert 
a new node with given data in BST */
Node* insert(Node* node, int data)
{
    /* If the tree is empty, 
       return a new node */
    if (node == NULL)
        return newNode(data);
  
    /* Otherwise, recur down the tree */
    if (data <= node->data)
        node->left = insert(node->left, data);
    else
        node->right = insert(node->right, data);
  
    /* return the (unchanged) node pointer */
    return node;
}
  
// Driver code
int main()
{
    /* Let us create following BST 
            50 
        / \ 
        30 70 
        / \ / \ 
    20 40 60 80 */
    Node* root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
  
    modifyBST(root);
  
    // print inoder tarversal of the modified BST
    inorder(root);
  
    return 0;
}
  
// This code is contributed by rathbhupendra


C
// C program to add all greater
// values in every node of BST
#include 
#include 
  
struct Node {
    int data;
    struct Node *left, *right;
};
  
// A utility function to create a new BST node
struct Node* newNode(int item)
{
    struct Node* temp
        = (struct Node*)malloc(
            sizeof(struct Node));
    temp->data = item;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Recursive function to add
// all greater values in every node
void modifyBSTUtil(
    struct Node* root, int* sum)
{
    // Base Case
    if (root == NULL)
        return;
  
    // Recur for right subtree
    modifyBSTUtil(root->right, sum);
  
    // Now *sum has sum of nodes
    // in right subtree, add
    // root->data to sum and
    // update root->data
    *sum = *sum + root->data;
    root->data = *sum;
  
    // Recur for left subtree
    modifyBSTUtil(root->left, sum);
}
  
// A wrapper over modifyBSTUtil()
void modifyBST(struct Node* root)
{
    int sum = 0;
    modifyBSTUtil(root, &sum);
}
  
// A utility function to do
// inorder traversal of BST
void inorder(struct Node* root)
{
    if (root != NULL) {
        inorder(root->left);
        printf("%d ", root->data);
        inorder(root->right);
    }
}
  
/* A utility function to insert 
a new node with given data in BST */
struct Node* insert(
    struct Node* node, int data)
{
    /* If the tree is empty, return a new node */
    if (node == NULL)
        return newNode(data);
  
    /* Otherwise, recur down the tree */
    if (data <= node->data)
        node->left = insert(node->left, data);
    else
        node->right = insert(node->right, data);
  
    /* return the (unchanged) node pointer */
    return node;
}
  
// Driver Program to test above functions
int main()
{
    /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
    struct Node* root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
  
    modifyBST(root);
  
    // print inoder tarversal of the modified BST
    inorder(root);
  
    return 0;
}


Java
// Java code to add all greater values to
// every node in a given BST
  
// A binary tree node
class Node {
  
    int data;
    Node left, right;
  
    Node(int d)
    {
        data = d;
        left = right = null;
    }
}
  
class BinarySearchTree {
  
    // Root of BST
    Node root;
  
    // Constructor
    BinarySearchTree()
    {
        root = null;
    }
  
    // Inorder traversal of the tree
    void inorder()
    {
        inorderUtil(this.root);
    }
  
    // Utility function for inorder traversal of
    // the tree
    void inorderUtil(Node node)
    {
        if (node == null)
            return;
  
        inorderUtil(node.left);
        System.out.print(node.data + " ");
        inorderUtil(node.right);
    }
  
    // adding new node
    public void insert(int data)
    {
        this.root = this.insertRec(this.root, data);
    }
  
    /* A utility function to insert a new node with 
    given data in BST */
    Node insertRec(Node node, int data)
    {
        /* If the tree is empty, return a new node */
        if (node == null) {
            this.root = new Node(data);
            return this.root;
        }
  
        /* Otherwise, recur down the tree */
        if (data <= node.data) {
            node.left = this.insertRec(node.left, data);
        }
        else {
            node.right = this.insertRec(node.right, data);
        }
        return node;
    }
  
    // This class initialises the value of sum to 0
    public class Sum {
        int sum = 0;
    }
  
    // Recursive function to add all greater values in
    // every node
    void modifyBSTUtil(Node node, Sum S)
    {
        // Base Case
        if (node == null)
            return;
  
        // Recur for right subtree
        this.modifyBSTUtil(node.right, S);
  
        // Now *sum has sum of nodes in right subtree, add
        // root->data to sum and update root->data
        S.sum = S.sum + node.data;
        node.data = S.sum;
  
        // Recur for left subtree
        this.modifyBSTUtil(node.left, S);
    }
  
    // A wrapper over modifyBSTUtil()
    void modifyBST(Node node)
    {
        Sum S = new Sum();
        this.modifyBSTUtil(node, S);
    }
  
    // Driver Function
    public static void main(String[] args)
    {
        BinarySearchTree tree = new BinarySearchTree();
  
        /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
  
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);
  
        tree.modifyBST(tree.root);
  
        // print inoder tarversal of the modified BST
        tree.inorder();
    }
}
  
// This code is contributed by Kamal Rawal


Python3
# Python3 program to add all greater values 
# in every node of BST 
  
# A utility function to create a
# new BST node 
class newNode: 
  
    # Constructor to create a new node 
    def __init__(self, data): 
        self.data = data 
        self.left = None
        self.right = None
  
# Recursive function to add all greater
# values in every node 
def modifyBSTUtil(root, Sum):
      
    # Base Case 
    if root == None:
        return
  
    # Recur for right subtree 
    modifyBSTUtil(root.right, Sum) 
  
    # Now Sum[0] has sum of nodes in right 
    # subtree, add root.data to sum and
    # update root.data 
    Sum[0] = Sum[0] + root.data 
    root.data = Sum[0]
  
    # Recur for left subtree 
    modifyBSTUtil(root.left, Sum)
  
# A wrapper over modifyBSTUtil() 
def modifyBST(root):
    Sum = [0]
    modifyBSTUtil(root, Sum)
  
# A utility function to do inorder
# traversal of BST 
def inorder(root):
    if root != None:
        inorder(root.left)
        print(root.data, end =" ") 
        inorder(root.right)
  
# A utility function to insert a new node 
# with given data in BST
def insert(node, data):
      
    # If the tree is empty, return a new node
    if node == None:
        return newNode(data)
  
    # Otherwise, recur down the tree
    if data <= node.data: 
        node.left = insert(node.left, data) 
    else:
        node.right = insert(node.right, data)
  
    # return the (unchanged) node pointer
    return node
  
# Driver Code
if __name__ == '__main__':
      
    # Let us create following BST 
    # 50 
    #     /     \ 
    # 30     70 
    #     / \ / \ 
    # 20 40 60 80
    root = None
    root = insert(root, 50) 
    insert(root, 30) 
    insert(root, 20) 
    insert(root, 40) 
    insert(root, 70) 
    insert(root, 60) 
    insert(root, 80) 
  
    modifyBST(root) 
  
    # print inoder tarversal of the
    # modified BST 
    inorder(root)
      
# This code is contributed by PranchalK


C#
using System;
  
// C# code to add all greater values to
// every node in a given BST
  
// A binary tree node
public class Node {
  
    public int data;
    public Node left, right;
  
    public Node(int d)
    {
        data = d;
        left = right = null;
    }
}
  
public class BinarySearchTree {
  
    // Root of BST
    public Node root;
  
    // Constructor
    public BinarySearchTree()
    {
        root = null;
    }
  
    // Inorder traversal of the tree
    public virtual void inorder()
    {
        inorderUtil(this.root);
    }
  
    // Utility function for inorder traversal of
    // the tree
    public virtual void inorderUtil(Node node)
    {
        if (node == null) {
            return;
        }
  
        inorderUtil(node.left);
        Console.Write(node.data + " ");
        inorderUtil(node.right);
    }
  
    // adding new node
    public virtual void insert(int data)
    {
        this.root = this.insertRec(this.root, data);
    }
  
    /* A utility function to insert a new node with  
    given data in BST */
    public virtual Node insertRec(Node node, int data)
    {
        /* If the tree is empty, return a new node */
        if (node == null) {
            this.root = new Node(data);
            return this.root;
        }
  
        /* Otherwise, recur down the tree */
        if (data <= node.data) {
            node.left = this.insertRec(node.left, data);
        }
        else {
            node.right = this.insertRec(node.right, data);
        }
        return node;
    }
  
    // This class initialises the value of sum to 0
    public class Sum {
        private readonly BinarySearchTree outerInstance;
  
        public Sum(BinarySearchTree outerInstance)
        {
            this.outerInstance = outerInstance;
        }
  
        public int sum = 0;
    }
  
    // Recursive function to add all greater values in
    // every node
    public virtual void modifyBSTUtil(Node node, Sum S)
    {
        // Base Case
        if (node == null) {
            return;
        }
  
        // Recur for right subtree
        this.modifyBSTUtil(node.right, S);
  
        // Now *sum has sum of nodes in right subtree, add
        // root->data to sum and update root->data
        S.sum = S.sum + node.data;
        node.data = S.sum;
  
        // Recur for left subtree
        this.modifyBSTUtil(node.left, S);
    }
  
    // A wrapper over modifyBSTUtil()
    public virtual void modifyBST(Node node)
    {
        Sum S = new Sum(this);
        this.modifyBSTUtil(node, S);
    }
  
    // Driver Function
    public static void Main(string[] args)
    {
        BinarySearchTree tree = new BinarySearchTree();
  
        /* Let us create following BST 
              50 
           /     \ 
          30      70 
         /  \    /  \ 
       20   40  60   80 */
  
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);
  
        tree.modifyBST(tree.root);
  
        // print inoder tarversal of the modified BST
        tree.inorder();
    }
}
  
// This code is contributed by Shrikant13


输出:

350 330 300 260 210 150 80

复杂度分析:

  • 时间复杂度: O(n)。
    由于此问题使用有序树遍历技术
  • 辅助空间: O(1)。
    由于尚未使用任何数据结构来存储值。

附带说明一下,我们还可以使用反向有序遍历来查找BST中的第k个最大元素。