📌  相关文章
📜  根据给定的遍历构造BST |套装2

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

给定二元搜索树的遍历顺序,构造BST。

例如,如果给定的遍历为{10,5,1,7,7,40,50},则输出应为下一棵树的根。

10
   /   \
  5     40
 /  \      \
1    7      50  

在上一篇文章中,我们讨论了O(n ^ 2)和O(n)递归解。以下是在O(n)时间内有效的基于堆栈的迭代解决方案。

1.创建一个空堆栈。

2.将第一个值设为root。将其推入堆栈。

3.在堆栈不为空且下一个值大于堆栈的最高值时继续弹出。将此值作为最后弹出节点的右子级。将新节点推入堆栈。

4.如果下一个值小于堆栈的最高值,则将该值作为堆栈的最高节点的左子节点。将新节点推入堆栈。

5.重复步骤2和3,直到pre []中剩余所有项目。

C++
// A O(n) iterative program for construction of BST from preorder traversal
#include 
using namespace std;
  
/* A binary tree node has data, pointer to left child 
and a pointer to right child */
class Node 
{ 
    public:
    int data; 
    Node *left, *right; 
} node; 
  
// A Stack has array of Nodes, capacity, and top 
class Stack 
{ 
    public:
    int top; 
    int capacity; 
    Node** array; 
} stack; 
  
// A utility function to create a new tree node 
Node* newNode( int data ) 
{ 
    Node* temp = new Node(); 
    temp->data = data; 
    temp->left = temp->right = NULL; 
    return temp; 
} 
  
// A utility function to create a stack of given capacity 
Stack* createStack( int capacity ) 
{ 
    Stack* stack = new Stack(); 
    stack->top = -1; 
    stack->capacity = capacity; 
    stack->array = new Node*[stack->capacity * sizeof( Node* )]; 
    return stack; 
} 
  
// A utility function to check if stack is full 
int isFull( Stack* stack ) 
{ 
    return stack->top == stack->capacity - 1; 
} 
  
// A utility function to check if stack is empty 
int isEmpty( Stack* stack ) 
{ 
    return stack->top == -1; 
} 
  
// A utility function to push an item to stack 
void push( Stack* stack, Node* item ) 
{ 
    if( isFull( stack ) ) 
        return; 
    stack->array[ ++stack->top ] = item; 
} 
  
// A utility function to remove an item from stack 
Node* pop( Stack* stack ) 
{ 
    if( isEmpty( stack ) ) 
        return NULL; 
    return stack->array[ stack->top-- ]; 
} 
  
// A utility function to get top node of stack 
Node* peek( Stack* stack ) 
{ 
    return stack->array[ stack->top ]; 
} 
  
// The main function that constructs BST from pre[] 
Node* constructTree ( int pre[], int size ) 
{ 
    // Create a stack of capacity equal to size 
    Stack* stack = createStack( size ); 
  
    // The first element of pre[] is always root 
    Node* root = newNode( pre[0] ); 
  
    // Push root 
    push( stack, root ); 
  
    int i; 
    Node* temp; 
  
    // Iterate through rest of the size-1 items of given preorder array 
    for ( i = 1; i < size; ++i ) 
    { 
        temp = NULL; 
  
        /* Keep on popping while the next value is greater than 
        stack's top value. */
        while ( !isEmpty( stack ) && pre[i] > peek( stack )->data ) 
            temp = pop( stack ); 
  
        // Make this greater value as the right child
                // and push it to the stack
        if ( temp != NULL) 
        { 
            temp->right = newNode( pre[i] ); 
            push( stack, temp->right ); 
        } 
  
        // If the next value is less than the stack's top
                // value, make this value as the left child of the
                // stack's top node. Push the new node to stack
        else
        { 
            peek( stack )->left = newNode( pre[i] ); 
            push( stack, peek( stack )->left ); 
        } 
    } 
  
    return root; 
} 
  
  
// A utility function to print inorder traversal of a Binary Tree 
void printInorder (Node* node) 
{ 
    if (node == NULL) 
        return; 
    printInorder(node->left); 
    cout<data<<" "; 
    printInorder(node->right); 
} 
  
// Driver program to test above functions 
int main () 
{ 
    int pre[] = {10, 5, 1, 7, 40, 50}; 
    int size = sizeof( pre ) / sizeof( pre[0] ); 
  
    Node *root = constructTree(pre, size); 
  
    cout<<"Inorder traversal of the constructed tree: \n"; 
    printInorder(root); 
  
    return 0; 
} 
  
//This code is contributed by rathbhupendra


C
// A O(n) iterative program for construction of BST from preorder traversal
#include 
#include 
#include 
  
/* A binary tree node has data, pointer to left child
   and a pointer to right child */
typedef struct Node
{
    int data;
    struct Node *left, *right;
} Node;
  
// A Stack has array of Nodes, capacity, and top
typedef struct Stack
{
    int top;
    int capacity;
    Node* *array;
} Stack;
  
// A utility function to create a new tree node
Node* newNode( int data )
{
    Node* temp = (Node *)malloc( sizeof( Node ) );
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// A utility function to create a stack of given capacity
Stack* createStack( int capacity )
{
    Stack* stack = (Stack *)malloc( sizeof( Stack ) );
    stack->top = -1;
    stack->capacity = capacity;
    stack->array = (Node **)malloc( stack->capacity * sizeof( Node* ) );
    return stack;
}
  
// A utility function to check if stack is full
int isFull( Stack* stack )
{
    return stack->top == stack->capacity - 1;
}
  
// A utility function to check if stack is empty
int isEmpty( Stack* stack )
{
    return stack->top == -1;
}
  
// A utility function to push an item to stack
void push( Stack* stack, Node* item )
{
    if( isFull( stack ) )
        return;
    stack->array[ ++stack->top ] = item;
}
  
// A utility function to remove an item from stack
Node* pop( Stack* stack )
{
    if( isEmpty( stack ) )
        return NULL;
    return stack->array[ stack->top-- ];
}
  
// A utility function to get top node of stack
Node* peek( Stack* stack )
{
    return stack->array[ stack->top ];
}
  
// The main function that constructs BST from pre[]
Node* constructTree ( int pre[], int size )
{
    // Create a stack of capacity equal to size
    Stack* stack = createStack( size );
  
    // The first element of pre[] is always root
    Node* root = newNode( pre[0] );
  
    // Push root
    push( stack, root );
  
    int i;
    Node* temp;
  
    // Iterate through rest of the size-1 items of given preorder array
    for ( i = 1; i < size; ++i )
    {
        temp = NULL;
  
        /* Keep on popping while the next value is greater than
           stack's top value. */
        while ( !isEmpty( stack ) && pre[i] > peek( stack )->data )
            temp = pop( stack );
  
        // Make this greater value as the right child
        // and push it to the stack
        if ( temp != NULL)
        {
            temp->right = newNode( pre[i] );
            push( stack, temp->right );
        }
  
        // If the next value is less than the stack's top 
        // value, make this value as the left child of the
        // stack's top node. Push the new node to stack
        else
        {
            peek( stack )->left = newNode( pre[i] );
            push( stack, peek( stack )->left );
        }
    }
  
    return root;
}
  
  
// A utility function to print inorder traversal of a Binary Tree
void printInorder (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 pre[] = {10, 5, 1, 7, 40, 50};
    int size = sizeof( pre ) / sizeof( pre[0] );
  
    Node *root = constructTree(pre, size);
  
    printf("Inorder traversal of the constructed tree: \n");
    printInorder(root);
  
    return 0;
}


Java
// Java program to construct BST from given preorder traversal
  
import java.util.*;
  
// A binary tree node
class Node {
  
    int data;
    Node left, right;
  
    Node(int d) {
        data = d;
        left = right = null;
    }
}
  
class BinaryTree {
  
    // The main function that constructs BST from pre[]
    Node constructTree(int pre[], int size) {
  
        // The first element of pre[] is always root
        Node root = new Node(pre[0]);
  
        Stack s = new Stack();
  
        // Push root
        s.push(root);
  
        // Iterate through rest of the size-1 items of given preorder array
        for (int i = 1; i < size; ++i) {
            Node temp = null;
  
            /* Keep on popping while the next value is greater than
             stack's top value. */
            while (!s.isEmpty() && pre[i] > s.peek().data) {
                temp = s.pop();
            }
  
            // Make this greater value as the right child
            // and push it to the stack
            if (temp != null) {
                temp.right = new Node(pre[i]);
                s.push(temp.right);
            } 
              
            // If the next value is less than the stack's top
            // value, make this value as the left child of the 
            // stack's top node. Push the new node to stack
            else {
                temp = s.peek();
                temp.left = new Node(pre[i]);
                s.push(temp.left);
            }
        }
  
        return root;
    }
  
    // 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 pre[] = new int[]{10, 5, 1, 7, 40, 50};
        int size = pre.length;
        Node root = tree.constructTree(pre, size);
        System.out.println("Inorder traversal of the constructed tree is ");
        tree.printInorder(root);
    }
}
  
// This code has been contributed by Mayank Jaiswal


Python3
# Python3 program to construct BST 
# from given preorder traversal
  
# A binary tree node
class Node:
  
    def __init__(self, data = 0):
        self.data = data
        self.left = None
        self.right = None
  
class BinaryTree :
  
    # The main function that constructs BST from pre[]
    def constructTree(self, pre, size): 
  
        # The first element of pre[] is always root
        root = Node(pre[0])
  
        s = []
  
        # append root
        s.append(root)
  
        i = 1
  
        # Iterate through rest of the size-1
        # items of given preorder array
        while ( i < size): 
            temp = None
  
            # Keep on popping while the next value 
            # is greater than stack's top value. 
            while (len(s) > 0 and pre[i] > s[-1].data): 
                temp = s.pop()
              
            # Make this greater value as the right child
            # and append it to the stack
            if (temp != None): 
                temp.right = Node(pre[i])
                s.append(temp.right)
              
            # If the next value is less than the stack's top
            # value, make this value as the left child of the 
            # stack's top node. append the new node to stack
            else :
                temp = s[-1]
                temp.left = Node(pre[i])
                s.append(temp.left)
            i = i + 1
          
        return root
      
    # A utility function to print 
    # inorder traversal of a Binary Tree
    def printInorder(self,node): 
        if (node == None): 
            return
          
        self.printInorder(node.left)
        print(node.data, end = " ")
        self.printInorder(node.right)
  
# Driver code
tree = BinaryTree()
pre = [10, 5, 1, 7, 40, 50]
size = len(pre)
root = tree.constructTree(pre, size)
print("Inorder traversal of the constructed tree is ")
tree.printInorder(root)
  
# This code is contributed by Arnab Kundu


C#
using System;
using System.Collections.Generic;
  
// c# program to construct BST from given preorder traversal 
  
// 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 BinaryTree
{
  
    // The main function that constructs BST from pre[] 
    public virtual Node constructTree(int[] pre, int size)
    {
  
        // The first element of pre[] is always root 
        Node root = new Node(pre[0]);
  
        Stack s = new Stack();
  
        // Push root 
        s.Push(root);
  
        // Iterate through rest of the size-1 items of given preorder array 
        for (int i = 1; i < size; ++i)
        {
            Node temp = null;
  
            /* Keep on popping while the next value is greater than 
             stack's top value. */
            while (s.Count > 0 && pre[i] > s.Peek().data)
            {
                temp = s.Pop();
            }
  
            // Make this greater value as the right child
            // and push it to the stack 
            if (temp != null)
            {
                temp.right = new Node(pre[i]);
                s.Push(temp.right);
            }
  
            // If the next value is less than the stack's top
            // value, make this value as the left child of the 
            // stack's top node. Push the new node to stack 
            else
            {
                temp = s.Peek();
                temp.left = new Node(pre[i]);
                s.Push(temp.left);
            }
        }
  
        return root;
    }
  
    // A utility function to print inorder traversal of a Binary Tree 
    public virtual void printInorder(Node node)
    {
        if (node == null)
        {
            return;
        }
        printInorder(node.left);
        Console.Write(node.data + " ");
        printInorder(node.right);
    }
  
    // Driver program to test above functions 
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
        int[] pre = new int[]{10, 5, 1, 7, 40, 50};
        int size = pre.Length;
        Node root = tree.constructTree(pre, size);
        Console.WriteLine("Inorder traversal of the constructed tree is ");
        tree.printInorder(root);
    }
}
  
  // This code is contributed by Shrikant13


输出:

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

时间复杂度: O(n)。从第一眼看,复杂性看起来更多。如果我们仔细观察,可以观察到每个项目仅被推送和弹出一次。因此,在constructTree()的主循环中最多执行2n次推/弹出操作。因此,时间复杂度为O(n)。