给定二叉搜索树的后序遍历,构造BST。
例如,
1.如果给定的遍历为{1、7、5、50、40、10},则应构造下一个树,并应返回树的根。
10
/ \
5 40
/ \ \
1 7 50
Input : 1 7 5 50 40 10
Output :
Inorder traversal of the constructed tree:
1 5 7 10 40 50
If the given traversal is {2, 6, 4, 9, 13, 11, 7}, then following tree should be constructed and root of the tree should be returned.
Input : 2 6 4 9 13 11 7
Output :
Inorder traversal of the constructed tree:
2 4 6 7 9 11 13
首先让我们看一下工作中的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 */