📌  相关文章
📜  使用Stack根据给定的后序遍历构造BST

📅  最后修改于: 2021-05-24 22:26:43             🧑  作者: Mango

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

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

10
   /   \
  5     40
 /  \      \
1    7      50

首先让我们看一下工作中的Postorder遍历。

7
     /   \
    4     11
   / \    /  \
  2   6  9    13

算法:

  • 将BST的根推入堆栈,即数组的最后一个元素。
  • 如果下一个元素>堆栈顶部的元素,则开始反向遍历数组,
    将此元素设置为该元素在堆栈顶部的右子元素,并将其推入堆栈。
  • 否则,如果下一个元素是<堆栈顶部的元素,那么,
    开始从堆栈中弹出所有元素,直到堆栈为空或当前元素变为>堆栈顶部的元素。
  • 使此元素成为最后弹出节点的子元素,然后重复上述步骤,直到完全遍历数组为止。

下面是上述算法的实现。

C++
Left
Right 
Root
Hence last node of post order will be root of tree, create it and push to stack.
If next element(i-1) is greater then it should be in right subtree.
If next element(i-1) is less then it should be in left subtree.


Java
// C++ implementation of the algorithm
/* A binary tree node has data, 
pointer to left child and a pointer
to right child */
#include
using namespace std;
  
// Class Node has data and references 
// to the left and the right child.
class Node
{
    public:
    int data;
    Node* left, *right;
  
    Node(int data)
    {
        this->data = data;
        left = right = NULL;
    }
};
  
// Function that creates the tree
Node* constructTreeUtil(int post[], int n)
{
    // Last node is root
    Node* root = new Node(post[n - 1]);
    stack s;
    s.push(root);
  
    // Traverse from second last node
    for (int i = n - 2; i >= 0; --i)
    {
        Node* x = new Node(post[i]);
  
        // Keep popping nodes while top() 
        // of stack is greater.
        Node* temp = NULL;
        while (s.size() && 
               post[i] < s.top()->data) 
            temp = s.top(), s.pop();     
  
        // Make x as left child of temp 
        if (temp != NULL) 
            temp->left = x;     
  
        // Else make x as right of top     
        else
            s.top()->right = x;
        s.push(x);
    }
    return root;
}
  
// Function that calls the method
// which contructs the tree
Node* constructTree(int post[], int size)
{
    return constructTreeUtil(post, size);
}
  
// A utility function to print 
// inorder traversal of a Binary Tree
void printInorder(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(int);
  
    Node* root = constructTree(post, size);
  
    cout << "Inorder traversal of " 
         << "the constructed tree:\n";
    printInorder(root);
}
  
// This code is contributed by Arnab Kundu


Python3
// Java implementation of the algorithm
/* A binary tree node has data, pointer to left child 
and a pointer to right child */
import java.util.*;
  
// Class Node has data and references to the left 
// and the right child.
class Node {
    int data;
    Node left, right;
  
    Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
  
class BinaryTree {
  
    // Function that creates the tree
    Node constructTreeUtil(int post[], int n)
    {
        // Last node is root
        Node root = new Node(post[n - 1]);
        Stack s = new Stack<>();
        s.push(root);
  
        // Traverse from second last node
        for (int i = n - 2; i >= 0; --i) {
              
            Node x = new Node(post[i]);
  
            // Keep popping nodes while top() of stack
            // is greater.
            Node temp = null;
            while (!s.isEmpty() && post[i] < s.peek().data) 
                temp = s.pop();      
  
            // Make x as left child of temp   
            if (temp != null) 
                temp.left = x;      
  
            // Else make x as right of top      
            else
                s.peek().right = x;
            s.push(x);
        }
        return root;
    }
  
    // Function that calls the method which contructs the tree
    Node constructTree(int post[], int size)
    {
        return constructTreeUtil(post, 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);
    }
}


C#
# Python3 implementation of the algorithm
# A binary tree node has data, 
# pointer to left child and a pointer
# to right child 
  
# Class Node has data and references 
# to the left and the right child.
class Node:
    def __init__(self, data = 0):
        self.data = data
        self.left = None
        self.right = None
      
# Function that creates the tree
def constructTreeUtil(post , n):
  
    # Last node is root
    root = Node(post[n - 1])
    s = []
    s.append(root)
    i = n - 2
  
    # Traverse from second last node
    while ( i >= 0):
        x = Node(post[i])
  
        # Keep popping nodes while top() 
        # of stack is greater.
        temp = None
        while (len(s) > 0 and post[i] < s[-1].data) :
            temp = s[-1]
            s.pop()     
  
        # Make x as left child of temp 
        if (temp != None): 
            temp.left = x     
  
        # Else make x as right of top     
        else:
            s[-1].right = x
        s.append(x)
        i = i - 1
      
    return root
  
# Function that calls the method
# which contructs the tree
def constructTree( post, size):
    return constructTreeUtil(post, size)
  
# A utility function to print 
# inorder traversal of a Binary Tree
def printInorder( node):
    if (node == None):
        return
    printInorder(node.left)
    print( node.data, end = " ")
    printInorder(node.right)
  
# Driver Code
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 Arnab Kundu


输出:
// C# implementation of the algorithm
  
/* A binary tree node has data, 
pointer to left child 
and a pointer to right child */
using System;
using System.Collections.Generic;
  
// Class Node has data and references  
// to the left and the right child.
public class Node 
{
    public int data;
    public Node left, right;
  
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
  
public class BinaryTree 
{
  
    // Function that creates the tree
    Node constructTreeUtil(int []post, int n)
    {
        // Last node is root
        Node root = new Node(post[n - 1]);
        Stack s = new Stack();
        s.Push(root);
  
        // Traverse from second last node
        for (int i = n - 2; i >= 0; --i) 
        {
              
            Node x = new Node(post[i]);
  
            // Keep popping nodes while top() of stack
            // is greater.
            Node temp = null;
            while (s.Count!=0 && post[i] < s.Peek().data) 
                temp = s.Pop();     
  
            // Make x as left child of temp 
            if (temp != null) 
                temp.left = x;     
  
            // Else make x as right of top     
            else
                s.Peek().right = x;
            s.Push(x);
        }
        return root;
    }
  
    // Function that calls the
    // method which contructs the tree
    Node constructTree(int []post, int size)
    {
        return constructTreeUtil(post, 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()
    {
        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 contributed by PrinciRaj1992 */