📜  从给定的后序构造一个二叉搜索树

📅  最后修改于: 2021-05-24 23:57:39             🧑  作者: Mango

给定二叉搜索树的后序遍历,构造BST。

例如,如果给定的遍历为{1、7、5、50、40、10},则应构造下一个树,并应返回树的根。

10
   /   \
  5     40
 /  \      \
1    7      50

方法1(O(n ^ 2)时间复杂度)
后遍历的最后一个元素始终是root。我们首先构建根。然后我们找到最后一个元素的索引,该索引小于根。令索引为“ i”。 0和’i’之间的值是左子树的一部分,而’i + 1’和’n-2’之间的值是右子树的一部分。在索引“ i”处划分给定的post []并针对左右子树重复出现。
例如,在{1、7、5、40、50、10}中,10是最后一个元素,因此我们将其设为根。现在,我们寻找小于10的最后一个元素,找到5。因此,我们知道BST的结构如下。

10
           /    \
          /      \
  {1, 7, 5}       {50, 40}

我们针对子数组{1,7,5}和{40,50}递归地执行上述步骤,并获得完整的树。

方法2(O(n)时间复杂度)
诀窍是为每个节点设置一个范围{min .. max}。将范围初始化为{INT_MIN .. INT_MAX}。最后一个节点肯定在范围内,因此请创建根节点。要构造左子树,请将范围设置为{INT_MIN…root-> data}。如果值在{INT_MIN .. root-> data}范围内,则这些值是左子树的一部分。要构建正确的子树,请将范围设置为{root-> data .. INT_MAX}。

以下代码用于生成给定后继遍历的确切二进制搜索树。

C++
/* A O(n) program for construction of 
BST from postorder traversal */
#include 
using namespace std;
  
/* A binary tree node has data, 
pointer to left child and a 
pointer to right child */
struct node
{
    int data;
    struct node *left, *right;
};
  
// A utility function to create a node
struct node* newNode (int data)
{
    struct node* temp =
(struct node *) malloc(sizeof(struct node));
  
    temp->data = data;
    temp->left = temp->right = NULL;
  
    return temp;
}
  
// A recursive function to construct 
// BST from post[]. postIndex is used 
// to keep track of index in post[].
struct node* constructTreeUtil(int post[], int* postIndex,
                               int key, int min, int max, 
                               int size)
{
    // Base case
    if (*postIndex < 0)
        return NULL;
  
    struct node* root = NULL;
  
    // If current element of post[] is 
    // in range, then only it is part
    // of current subtree
    if (key > min && key < max)
    {
        // Allocate memory for root of this 
        // subtree and decrement *postIndex
        root = newNode(key);
        *postIndex = *postIndex - 1;
  
        if (*postIndex >= 0)
        {
  
        // All nodes which are in range {key..max} 
        // will go in right subtree, and first such 
        // node will be root of right subtree.
        root->right = constructTreeUtil(post, postIndex, 
                                        post[*postIndex],
                                        key, max, size );
  
        // Construct the subtree under root
        // All nodes which are in range {min .. key} 
        // will go in left subtree, and first such
        // node will be root of left subtree.
        root->left = constructTreeUtil(post, postIndex,
                                       post[*postIndex],
                                       min, key, size );
        }
    }
    return root;
}
  
// The main function to construct BST 
// from given postorder traversal.
// This function mainly uses constructTreeUtil()
struct node *constructTree (int post[], 
                            int size)
{
    int postIndex = size-1;
    return constructTreeUtil(post, &postIndex, 
                             post[postIndex],
                             INT_MIN, INT_MAX, size);
}
  
// A utility function to print
// inorder traversal of a Binary Tree
void printInorder (struct node* node)
{
    if (node == NULL)
        return;
    printInorder(node->left);
    cout << node->data << " ";
    printInorder(node->right);
}
  
// Driver Code
int main ()
{
    int post[] = {1, 7, 5, 50, 40, 10};
    int size = sizeof(post) / sizeof(post[0]);
  
    struct node *root = constructTree(post, size);
  
    cout << "Inorder traversal of "
        << "the constructed tree: \n";
    printInorder(root);
  
    return 0;
}
  
// This code is contributed
// by Akanksha Rai


C
/* A O(n) program for construction of BST from
   postorder traversal */
#include 
#include 
#include 
  
/* A binary tree node has data, pointer to left child
   and a pointer to right child */
struct node
{
    int data;
    struct node *left, *right;
};
  
// A utility function to create a node
struct node* newNode (int data)
{
    struct node* temp =
        (struct node *) malloc( sizeof(struct node));
  
    temp->data = data;
    temp->left = temp->right = NULL;
  
    return temp;
}
  
// A recursive function to construct BST from post[]. 
// postIndex is used to keep track of index in post[].
struct node* constructTreeUtil(int post[], int* postIndex,
                         int key, int min, int max, int size)
{
    // Base case
    if (*postIndex < 0)
        return NULL;
  
    struct node* root = NULL;
  
    // If current element of post[] is in range, then
    // only it is part of current subtree
    if (key > min && key < max)
    {
        // Allocate memory for root of this subtree and decrement
        // *postIndex
        root = newNode(key);
        *postIndex = *postIndex - 1;
  
        if (*postIndex >= 0)
        {
  
          // All nodes which are in range {key..max} will go in right
          // subtree, and first such node will be root of right subtree.
          root->right = constructTreeUtil(post, postIndex, post[*postIndex],
                                          key, max, size );
  
          // Construct the subtree under root
          // All nodes which are in range {min .. key} will go in left
          // subtree, and first such node will be root of left subtree.
          root->left = constructTreeUtil(post, postIndex, post[*postIndex],
                                         min, key, size );
        }
    }
    return root;
}
  
// The main function to construct BST from given postorder
// traversal. This function mainly uses constructTreeUtil()
struct node *constructTree (int post[], int size)
{
    int postIndex = size-1;
    return constructTreeUtil(post, &postIndex, post[postIndex],
                             INT_MIN, INT_MAX, size);
}
  
// A utility function to print inorder traversal of a Binary Tree
void printInorder (struct node* node)
{
    if (node == NULL)
        return;
    printInorder(node->left);
    printf("%d ", node->data);
    printInorder(node->right);
}
  
// Driver program to test above functions
int main ()
{
    int post[] = {1, 7, 5, 50, 40, 10};
    int size = sizeof(post) / sizeof(post[0]);
  
    struct node *root = constructTree(post, size);
  
    printf("Inorder traversal of the constructed tree: \n");
    printInorder(root);
  
    return 0;
}


Java
/* A O(n) program for construction of BST from
   postorder traversal */
  
 /* A binary tree node has data, pointer to left child
   and a pointer to right child */
class Node 
{
    int data;
    Node left, right;
  
    Node(int data) 
    {
        this.data = data;
        left = right = null;
    }
}
  
// Class containing variable that keeps a track of overall
// calculated postindex
class Index 
{
    int postindex = 0;
}
  
class BinaryTree 
{
    // A recursive function to construct BST from post[]. 
    // postIndex is used to keep track of index in post[].
    Node constructTreeUtil(int post[], Index postIndex,
            int key, int min, int max, int size) 
    {
        // Base case
        if (postIndex.postindex < 0)
            return null;
  
        Node root = null;
  
        // If current element of post[] is in range, then
        // only it is part of current subtree
        if (key > min && key < max) 
        {
            // Allocate memory for root of this subtree and decrement
            // *postIndex
            root = new Node(key);
            postIndex.postindex = postIndex.postindex - 1;
  
            if (postIndex.postindex > 0) 
            {
                // All nodes which are in range {key..max} will go in 
                // right subtree, and first such node will be root of right
                // subtree
                root.right = constructTreeUtil(post, postIndex, 
                        post[postIndex.postindex],key, max, size);
  
                // Construct the subtree under root
                // All nodes which are in range {min .. key} will go in left
                // subtree, and first such node will be root of left subtree.
                root.left = constructTreeUtil(post, postIndex, 
                        post[postIndex.postindex],min, key, size);
            }
        }
        return root;
    }
  
    // The main function to construct BST from given postorder
    // traversal. This function mainly uses constructTreeUtil()
    Node constructTree(int post[], int size) 
    {
        Index index = new Index();
        index.postindex = size - 1;
        return constructTreeUtil(post, index, post[index.postindex],
                Integer.MIN_VALUE, Integer.MAX_VALUE, size);
    }
  
    // A utility function to print inorder traversal of a Binary Tree
    void printInorder(Node node) 
    {
        if (node == null)
            return;
        printInorder(node.left);
        System.out.print(node.data + " ");
        printInorder(node.right);
    }
  
    // Driver program to test above functions
    public static void main(String[] args) 
    {
        BinaryTree tree = new BinaryTree();
        int post[] = new int[]{1, 7, 5, 50, 40, 10};
        int size = post.length;
  
        Node root = tree.constructTree(post, size);
  
        System.out.println("Inorder traversal of the constructed tree:");
        tree.printInorder(root);
    }
}
  
// This code has been contributed by Mayank Jaiswal


Python3
# A O(n) program for construction of BST 
# from postorder traversal 
INT_MIN = -2**31
INT_MAX = 2**31
  
# A binary tree node has data, pointer to 
# left child and a pointer to right child
# A utility function to create a node 
class newNode: 
    def __init__(self, data): 
        self.data = data 
        self.left = self.right = None
          
# A recursive function to construct 
# BST from post[]. postIndex is used 
# to keep track of index in post[]. 
def constructTreeUtil(post, postIndex, 
                      key, min, max, size): 
  
    # Base case 
    if (postIndex[0] < 0):
        return None
  
    root = None
  
    # If current element of post[] is 
    # in range, then only it is part 
    # of current subtree 
    if (key > min and key < max) :
      
        # Allocate memory for root of this 
        # subtree and decrement *postIndex 
        root = newNode(key) 
        postIndex[0] = postIndex[0] - 1
  
        if (postIndex[0] >= 0) :
          
            # All nodes which are in range key..
            # max will go in right subtree, and 
            # first such node will be root of 
            # right subtree. 
            root.right = constructTreeUtil(post, postIndex,
                                           post[postIndex[0]], 
                                           key, max, size ) 
  
            # Construct the subtree under root 
            # All nodes which are in range min .. 
            # key will go in left subtree, and 
            # first such node will be root of 
            # left subtree. 
            root.left = constructTreeUtil(post, postIndex,
                                          post[postIndex[0]], 
                                          min, key, size ) 
          
    return root 
  
# The main function to construct BST 
# from given postorder traversal. This
# function mainly uses constructTreeUtil() 
def constructTree (post, size) :
  
    postIndex = [size-1]
    return constructTreeUtil(post, postIndex, 
                             post[postIndex[0]],
                             INT_MIN, INT_MAX, size) 
  
# A utility function to prinorder
# traversal of a Binary Tree 
def printInorder (node) :
  
    if (node == None) :
        return
    printInorder(node.left) 
    print(node.data, end = " ") 
    printInorder(node.right) 
  
# Driver Code 
if __name__ == '__main__':
    post = [1, 7, 5, 50, 40, 10]
    size = len(post) 
  
    root = constructTree(post, size) 
  
    print("Inorder traversal of the", 
                "constructed tree: ") 
    printInorder(root)
  
# This code is contributed 
# by SHUBHAMSINGH10


C#
using System;
/* A O(n) program for 
construction of BST from 
postorder traversal */
  
/* A binary tree node has data,
pointer to left child and a
 pointer to right child */
class Node 
{ 
    public int data; 
    public Node left, right; 
  
    public Node(int data) 
    { 
        this.data = data; 
        left = right = null; 
    } 
} 
  
// Class containing variable 
// that keeps a track of overall 
// calculated postindex 
class Index 
{ 
    public int postindex = 0; 
} 
  
public class BinaryTree 
{ 
    // A recursive function to 
    // construct BST from post[]. 
    // postIndex is used to 
    // keep track of index in post[]. 
    Node constructTreeUtil(int []post, Index postIndex, 
                    int key, int min, int max, int size) 
    { 
        // Base case 
        if (postIndex.postindex < 0) 
            return null; 
  
        Node root = null; 
  
        // If current element of post[] is in range, then 
        // only it is part of current subtree 
        if (key > min && key < max) 
        { 
            // Allocate memory for root of  
            // this subtree and decrement *postIndex 
            root = new Node(key); 
            postIndex.postindex = postIndex.postindex - 1; 
  
            if (postIndex.postindex > 0) 
            { 
                // All nodes which are in range
                // {key..max} will go in right subtree,
                // and first such node will be root of 
                // right subtree 
                root.right = constructTreeUtil(post, postIndex, 
                        post[postIndex.postindex], key, max, size); 
  
                // Construct the subtree under root 
                // All nodes which are in range
                // {min .. key} will go in left 
                // subtree, and first such node
                // will be root of left subtree. 
                root.left = constructTreeUtil(post, postIndex, 
                        post[postIndex.postindex],min, key, size); 
            } 
        } 
        return root; 
    } 
  
    // The main function to construct
    // BST from given postorder traversal.
    // This function mainly uses constructTreeUtil() 
    Node constructTree(int []post, int size) 
    { 
        Index index = new Index(); 
        index.postindex = size - 1; 
        return constructTreeUtil(post, index,
                        post[index.postindex], 
                        int.MinValue, int.MaxValue, size); 
    } 
  
    // A utility function to print
    // inorder traversal of a Binary Tree 
    void printInorder(Node node) 
    { 
        if (node == null) 
            return; 
        printInorder(node.left); 
        Console.Write(node.data + " "); 
        printInorder(node.right); 
    } 
  
    // Driver code 
    public static void Main(String[] args) 
    { 
        BinaryTree tree = new BinaryTree(); 
        int []post = new int[]{1, 7, 5, 50, 40, 10}; 
        int size = post.Length; 
  
        Node root = tree.constructTree(post, size); 
  
        Console.WriteLine("Inorder traversal of" +
                            "the constructed tree:"); 
        tree.printInorder(root); 
    } 
} 
  
// This code has been contributed by PrinciRaj1992


输出:

Inorder traversal of the constructed tree: 
1 5 7 10 40 50 

请注意,当我们打印二进制搜索树的有序遍历时,程序的输出将始终是排序后的序列。