📜  从前序遍历构造完美二叉树

📅  最后修改于: 2022-05-13 01:56:07.004000             🧑  作者: Mango

从前序遍历构造完美二叉树

给定一个数组pre[] ,表示由N个节点组成的完美二叉树的前序遍历,任务是从给定的前序遍历构造一个完美二叉树并返回树的根。

例子:

一般要构造二叉树,只用前序遍历是做不到的,但这里给出了一个额外的条件,即二叉树是完美二叉树。我们可以使用那个额外的条件。

对于完美二叉树,每个节点都有 2 个或 0 个子节点,并且所有叶节点都存在于同一级别。二叉树的前序遍历首先包含根,然后是左子树的前序遍历,然后是右子树的前序遍历。所以对于完美二叉树根应该在两个子树中具有相同数量的子树,因此在前序遍历中根之后的元素数量(例如,n)应该是偶数(2 * 一个子树中的节点数,因为它是完美的二叉树)。并且由于完美二叉树的每个子树的节点数相等,我们可以找到左子树的前序遍历(在整个树的前序遍历中,它是根之后的数组的一半),我们知道前序遍历右子树必须在左子树的前序遍历之后,所以剩下的一半是右子树的前序遍历。

所以前序遍历的第一个元素是根,我们会用这个元素构建一个节点作为根,那么我们可以很容易地找到根的左右子树的前序遍历,然后递归地构建左子树和右子树的前序遍历。根的右子树。

方法:给定的问题可以使用递归来解决。请按照以下步骤解决问题:

  • 创建一个函数,比如BuildPerfectBT_helper ,其参数为preStartpreEndpre[]其中preStart表示数组pre[] 的起始索引, preEnd 表示数组 pre[]结束索引,并执行以下步骤:
    • 如果preStart的值大于preEnd ,则返回NULL
    • root初始化为pre[preStart]
    • 如果preStart的值与preEnd相同,则返回root
    • 初始化 4 个变量,将 leftPreStart设为preStart + 1将 rightPreStart设为leftPreStart + (preEnd – leftPreStart+1)/2将 leftPreEnd设为rightPreStart – 1将 rightPreEnd设为preEnd
    • 通过使用参数leftPreStartleftPreEndpre[]递归调用函数buildPerfectBT_helper()来修改root->left的值。
    • 通过使用参数rightPreStartrightPreEndpre[]递归调用函数buildPerfectBT_helper()来修改root->right的值。
    • 执行上述步骤后,返回root
  • 创建完美二叉树后,打印树的中序遍历。

下面是讨论的上述步骤的图示:

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Structure of the tree
struct Node {
    int data;
    Node *left, *right;
 
    Node(int val)
    {
        data = val;
        left = right = NULL;
    }
};
 
// Function to create a new node with
// the value val
Node* getNewNode(int val)
{
    Node* newNode = new Node(val);
    newNode->data = val;
    newNode->left = newNode->right = NULL;
 
    // Return the newly created node
    return newNode;
}
 
// Function to create the Perfect
// Binary Tree
Node* buildPerfectBT_helper(int preStart,
                            int preEnd,
                            int pre[])
{
    // If preStart > preEnd return NULL
    if (preStart > preEnd)
        return NULL;
 
    // Initialize root as pre[preStart]
    Node* root = getNewNode(pre[preStart]);
    ;
 
    // If the only node is left,
    // then return node
    if (preStart == preEnd)
        return root;
 
    // Parameters for further recursion
    int leftPreStart = preStart + 1;
    int rightPreStart = leftPreStart
                        + (preEnd - leftPreStart + 1) / 2;
    int leftPreEnd = rightPreStart - 1;
    int rightPreEnd = preEnd;
 
    // Recursive Call to build the
    // subtree of root node
    root->left = buildPerfectBT_helper(
        leftPreStart, leftPreEnd, pre);
 
    root->right = buildPerfectBT_helper(
        rightPreStart, rightPreEnd, pre);
 
    // Return the created root
    return root;
}
 
// Function to build Perfect Binary Tree
Node* buildPerfectBT(int pre[], int size)
{
    return buildPerfectBT_helper(0, size - 1, pre);
}
 
// Function to print the Inorder of
// the given Tree
void printInorder(Node* root)
{
    // Base Case
    if (!root)
        return;
 
    // Left Recursive Call
    printInorder(root->left);
 
    // Print the data
    cout << root->data << " ";
 
    // Right Recursive Call
    printInorder(root->right);
}
 
// Driver Code
int main()
{
    int pre[] = { 1, 2, 4, 5, 3, 6, 7 };
    int N = sizeof(pre) / sizeof(pre[0]);
 
    // Function Call
    Node* root = buildPerfectBT(pre, N);
 
    // Print Inorder Traversal
    cout << "\nInorder traversal of the tree: ";
    printInorder(root);
 
    return 0;
}


Java
// Java program for the above approach
public class Main
{
    // Structure of the tree
    static class Node {
         
        public int data;
        public Node left, right;
         
        public Node(int val)
        {
            data = val;
            left = right = null;
        }
    }
     
    // Function to create a new node with
    // the value val
    static Node getNewNode(int val)
    {
        Node newNode = new Node(val);
       
        // Return the newly created node
        return newNode;
    }
   
    // Function to create the Perfect
    // Binary Tree
    static Node buildPerfectBT_helper(int preStart, int preEnd, int[] pre)
    {
        // If preStart > preEnd return NULL
        if (preStart > preEnd)
            return null;
   
        // Initialize root as pre[preStart]
        Node root = getNewNode(pre[preStart]);
   
        // If the only node is left,
        // then return node
        if (preStart == preEnd)
            return root;
   
        // Parameters for further recursion
        int leftPreStart = preStart + 1;
        int rightPreStart = leftPreStart + (preEnd - leftPreStart + 1) / 2;
        int leftPreEnd = rightPreStart - 1;
        int rightPreEnd = preEnd;
   
        // Recursive Call to build the
        // subtree of root node
        root.left = buildPerfectBT_helper(
            leftPreStart, leftPreEnd, pre);
   
        root.right = buildPerfectBT_helper(
            rightPreStart, rightPreEnd, pre);
   
        // Return the created root
        return root;
    }
   
    // Function to build Perfect Binary Tree
    static Node buildPerfectBT(int[] pre, int size)
    {
        return buildPerfectBT_helper(0, size - 1, pre);
    }
   
    // Function to print the Inorder of
    // the given Tree
    static void printInorder(Node root)
    {
        // Base Case
        if (root == null)
            return;
   
        // Left Recursive Call
        printInorder(root.left);
   
        // Print the data
        System.out.print(root.data + " ");
   
        // Right Recursive Call
        printInorder(root.right);
    }
     
    public static void main(String[] args) {
        int[] pre = { 1, 2, 4, 5, 3, 6, 7 };
        int N = pre.length;
       
        // Function Call
        Node root = buildPerfectBT(pre, N);
       
        // Print Inorder Traversal
        System.out.print("Inorder traversal of the tree: ");
        printInorder(root);
    }
}
 
// This code is contributed by suresh07.


Python3
# Python3 program for the above approach
 
# Structure of the tree
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
 
# Function to create a new node with
# the value val
def getNewNode(val):
    newNode = Node(val)
     
    # Return the newly created node
    return newNode
 
# Function to create the Perfect
# Binary Tree
def buildPerfectBT_helper(preStart, preEnd, pre):
   
    # If preStart > preEnd return NULL
    if (preStart > preEnd):
        return None
 
    # Initialize root as pre[preStart]
    root = getNewNode(pre[preStart])
 
    # If the only node is left,
    # then return node
    if (preStart == preEnd):
        return root
 
    # Parameters for further recursion
    leftPreStart = preStart + 1
    rightPreStart = leftPreStart + int((preEnd - leftPreStart + 1) / 2)
    leftPreEnd = rightPreStart - 1
    rightPreEnd = preEnd
 
    # Recursive Call to build the
    # subtree of root node
    root.left = buildPerfectBT_helper(leftPreStart, leftPreEnd, pre)
 
    root.right = buildPerfectBT_helper(rightPreStart, rightPreEnd, pre)
 
    # Return the created root
    return root
 
# Function to build Perfect Binary Tree
def buildPerfectBT(pre, size):
    return buildPerfectBT_helper(0, size - 1, pre)
 
# Function to print the Inorder of
# the given Tree
def printInorder(root):
   
    # Base Case
    if (root == None):
        return
 
    # Left Recursive Call
    printInorder(root.left)
 
    # Print the data
    print(root.data, "", end = "")
 
    # Right Recursive Call
    printInorder(root.right)
 
pre = [ 1, 2, 4, 5, 3, 6, 7 ]
N = len(pre)
 
# Function Call
root = buildPerfectBT(pre, N)
 
# Print Inorder Traversal
print("Inorder traversal of the tree: ", end = "")
printInorder(root)
 
# This code is contributed by decode2207.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Structure of the tree
    class Node {
        
        public int data;
        public Node left, right;
        
        public Node(int val)
        {
            data = val;
            left = right = null;
        }
    }
     
    // Function to create a new node with
    // the value val
    static Node getNewNode(int val)
    {
        Node newNode = new Node(val);
        // Return the newly created node
        return newNode;
    }
  
    // Function to create the Perfect
    // Binary Tree
    static Node buildPerfectBT_helper(int preStart, int preEnd, int[] pre)
    {
        // If preStart > preEnd return NULL
        if (preStart > preEnd)
            return null;
  
        // Initialize root as pre[preStart]
        Node root = getNewNode(pre[preStart]);
  
        // If the only node is left,
        // then return node
        if (preStart == preEnd)
            return root;
  
        // Parameters for further recursion
        int leftPreStart = preStart + 1;
        int rightPreStart = leftPreStart + (preEnd - leftPreStart + 1) / 2;
        int leftPreEnd = rightPreStart - 1;
        int rightPreEnd = preEnd;
  
        // Recursive Call to build the
        // subtree of root node
        root.left = buildPerfectBT_helper(
            leftPreStart, leftPreEnd, pre);
  
        root.right = buildPerfectBT_helper(
            rightPreStart, rightPreEnd, pre);
  
        // Return the created root
        return root;
    }
  
    // Function to build Perfect Binary Tree
    static Node buildPerfectBT(int[] pre, int size)
    {
        return buildPerfectBT_helper(0, size - 1, pre);
    }
  
    // Function to print the Inorder of
    // the given Tree
    static void printInorder(Node root)
    {
        // Base Case
        if (root == null)
            return;
  
        // Left Recursive Call
        printInorder(root.left);
  
        // Print the data
        Console.Write(root.data + " ");
  
        // Right Recursive Call
        printInorder(root.right);
    }
     
  static void Main() {
    int[] pre = { 1, 2, 4, 5, 3, 6, 7 };
    int N = pre.Length;
  
    // Function Call
    Node root = buildPerfectBT(pre, N);
  
    // Print Inorder Traversal
    Console.Write("Inorder traversal of the tree: ");
    printInorder(root);
  }
}
 
// This code is contributed by mukesh07.


Javascript


输出:
Inorder traversal of the tree: 4 2 5 1 6 3 7

时间复杂度: O(N)
辅助空间: O(N)