📌  相关文章
📜  使用它的前序遍历和镜像树的前序遍历构造完整的二叉树

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

使用它的前序遍历和镜像树的前序遍历构造完整的二叉树

给定两个表示完整二叉树及其镜像树的前序遍历的数组,我们需要编写一个程序来使用这两个前序遍历来构造二叉树。
完全二叉树是一棵二叉树,其中每个节点都有 0 或 2 个子节点。

注意:使用这两种遍历是不可能构造通用二叉树的。但是我们可以使用上述遍历创建一个完整的二叉树,而不会产生任何歧义。有关更多详细信息,请参阅本文。

例子:

Input :  preOrder[] = {1,2,4,5,3,6,7}
         preOrderMirror[] = {1,3,7,6,2,5,4}

Output :          1
               /    \
              2      3
            /   \   /  \
           4     5 6    7
  • 方法 1 :让我们考虑两个给定的数组 preOrder[] = {1, 2, 4, 5, 3, 6, 7} 和 preOrderMirror[] = {1 ,3 ,7 ,6 ,2 ,5 ,4} .
    在 preOrder[] 和 preOrderMirror[] 中,最左边的元素是树的根。由于树已满且数组大小大于 1。preOrder[] 中 1 旁边的值必须是 root 的左孩子,preOrderMirror[] 中 1 旁边的值必须是 root 的右孩子。所以我们知道 1 是根,2 是左孩子,3 是右孩子。如何找到左子树中的所有节点?我们知道 2 是左子树中所有节点的根,3 是右子树中所有节点的根。 preOrderMirror[] 中来自和 2 的所有节点必须在根节点 1 的左子树中,并且 preOrderMirror[] 中 3 之后和 2 之前的所有节点必须在根节点 1 的右子树中。现在我们知道 1 是根,元素 {2 , 5, 4} 在左子树中,元素 {3, 7, 6} 在右子树中。
1
        /    \
       /      \
    {2,5,4}  {3,7,6}
  • 我们将递归地遵循上述方法并得到以下树:
1
               /    \
              2      3
            /   \   /  \
           4     5 6    7

以下是上述方法的实现:

C++
// C++ program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
 
#include
using namespace std;
 
// A Binary Tree Node
struct Node
{
    int data;
    struct Node *left, *right;
};
 
// 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 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);
}
 
// A recursive function to construct Full binary tree
//  from pre[] and preM[]. preIndex is used to keep
// track of index in pre[]. l is low index and h is high
//index for the current subarray in preM[]
Node* constructBinaryTreeUtil(int pre[], int preM[],
                    int &preIndex, int l,int h,int size)
{   
    // Base case
    if (preIndex >= size || l > h)
        return NULL;
 
    // The first node in preorder traversal is root.
    // So take the node at preIndex from preorder and
    // make it root, and increment preIndex
    Node* root = newNode(pre[preIndex]);
        ++(preIndex);
 
    // If the current subarray has only one element,
    // no need to recur
    if (l == h)
        return root;
     
    // Search the next element of pre[] in preM[]
    int i;
    for (i = l; i <= h; ++i)
        if (pre[preIndex] == preM[i])
            break;
 
    // construct left and right subtrees recursively   
    if (i <= h)
    {
        root->left = constructBinaryTreeUtil (pre, preM,
                                    preIndex, i, h, size);
        root->right = constructBinaryTreeUtil (pre, preM,
                                 preIndex, l+1, i-1, size);
    }
  
     // return root
    return root;   
}
 
// function to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
void constructBinaryTree(Node* root,int pre[],
                        int preMirror[], int size)
{
    int preIndex = 0;
    int preMIndex = 0;
 
    root =  constructBinaryTreeUtil(pre,preMirror,
                            preIndex,0,size-1,size);
 
    printInorder(root);
}
 
// Driver program to test above functions
int main()
{
    int preOrder[] = {1,2,4,5,3,6,7};
    int preOrderMirror[] = {1,3,7,6,2,5,4};
 
    int size = sizeof(preOrder)/sizeof(preOrder[0]);
 
    Node* root = new Node;
 
    constructBinaryTree(root,preOrder,preOrderMirror,size);
 
    return 0;
}


Java
// Java program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
class GFG
{
 
// A Binary Tree Node
static class Node
{
    int data;
    Node left, right;
};
static class INT
{
    int a;
    INT(int a){this.a=a;}
}
 
// Utility function to create a new tree node
static Node newNode(int data)
{
    Node temp = new Node();
    temp.data = data;
    temp.left = temp.right = null;
    return temp;
}
 
// A utility function to print inorder traversal
// of a Binary Tree
static void printInorder(Node node)
{
    if (node == null)
        return;
 
    printInorder(node.left);
    System.out.printf("%d ", node.data);
    printInorder(node.right);
}
 
// A recursive function to construct Full binary tree
// from pre[] and preM[]. preIndex is used to keep
// track of index in pre[]. l is low index and h is high
//index for the current subarray in preM[]
static Node conBinaryTreeUtil(int pre[], int preM[],
                    INT preIndex, int l, int h, int size)
{
    // Base case
    if (preIndex.a >= size || l > h)
        return null;
 
    // The first node in preorder traversal is root.
    // So take the node at preIndex from preorder and
    // make it root, and increment preIndex
    Node root = newNode(pre[preIndex.a]);
        ++(preIndex.a);
 
    // If the current subarray has only one element,
    // no need to recur
    if (l == h)
        return root;
     
    // Search the next element of pre[] in preM[]
    int i;
    for (i = l; i <= h; ++i)
        if (pre[preIndex.a] == preM[i])
            break;
 
    // construct left and right subtrees recursively
    if (i <= h)
    {
        root.left = conBinaryTreeUtil (pre, preM,
                                    preIndex, i, h, size);
        root.right = conBinaryTreeUtil (pre, preM,
                                preIndex, l + 1, i - 1, size);
    }
 
    // return root
    return root;    
}
 
// function to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
static void conBinaryTree(Node root,int pre[],
                        int preMirror[], int size)
{
    INT preIndex = new INT(0);
    int preMIndex = 0;
 
    root = conBinaryTreeUtil(pre,preMirror,
                            preIndex, 0, size - 1, size);
 
    printInorder(root);
}
 
// Driver code
public static void main(String args[])
{
    int preOrder[] = {1,2,4,5,3,6,7};
    int preOrderMirror[] = {1,3,7,6,2,5,4};
 
    int size = preOrder.length;
 
    Node root = new Node();
 
    conBinaryTree(root,preOrder,preOrderMirror,size);
}
}
 
// This code is contributed by Arnab Kundu


Python3
# Python3 program to construct full binary
# tree using its preorder traversal and
# preorder traversal of its mirror tree
 
# Utility function to create a new tree node
class newNode:
    def __init__(self,data):
        self.data = data
        self.left = self.right = None
 
# A utility function to print inorder
# traversal of a Binary Tree
def prInorder(node):
    if (node == None) :
        return
    prInorder(node.left)
    print(node.data, end = " ")
    prInorder(node.right)
 
# A recursive function to construct Full 
# binary tree from pre[] and preM[].
# preIndex is used to keep track of index
# in pre[]. l is low index and h is high
# index for the current subarray in preM[]
def constructBinaryTreeUtil(pre, preM, preIndex,
                                    l, h, size):
    # Base case
    if (preIndex >= size or l > h) :
        return None , preIndex
 
    # The first node in preorder traversal 
    # is root. So take the node at preIndex
    # from preorder and make it root, and
    # increment preIndex
    root = newNode(pre[preIndex])
    preIndex += 1
 
    # If the current subarray has only
    # one element, no need to recur
    if (l == h):
        return root, preIndex
 
    # Search the next element of
    # pre[] in preM[]
    i = 0
    for i in range(l, h + 1):
        if (pre[preIndex] == preM[i]):
                break
 
    # construct left and right subtrees
    # recursively
    if (i <= h):
 
        root.left, preIndex = constructBinaryTreeUtil(pre, preM, preIndex,
                                                               i, h, size)
        root.right, preIndex = constructBinaryTreeUtil(pre, preM, preIndex,
                                                       l + 1, i - 1, size)
 
    # return root
    return root, preIndex
 
# function to construct full binary tree
# using its preorder traversal and preorder
# traversal of its mirror tree
def constructBinaryTree(root, pre, preMirror, size):
 
    preIndex = 0
    preMIndex = 0
 
    root, x = constructBinaryTreeUtil(pre, preMirror, preIndex,
                                             0, size - 1, size)
 
    prInorder(root)
 
# Driver code
if __name__ =="__main__":
 
    preOrder = [1, 2, 4, 5, 3, 6, 7]
    preOrderMirror = [1, 3, 7, 6, 2, 5, 4]
 
    size = 7
    root = newNode(0)
 
    constructBinaryTree(root, preOrder,
                        preOrderMirror, size)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#
// C# program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
using System;
     
class GFG
{
 
// A Binary Tree Node
public class Node
{
    public int data;
    public Node left, right;
};
public class INT
{
    public int a;
    public INT(int a){this.a=a;}
}
 
// Utility function to create a new tree node
static Node newNode(int data)
{
    Node temp = new Node();
    temp.data = data;
    temp.left = temp.right = null;
    return temp;
}
 
// A utility function to print inorder traversal
// of a Binary Tree
static void printInorder(Node node)
{
    if (node == null)
        return;
 
    printInorder(node.left);
    Console.Write("{0} ", node.data);
    printInorder(node.right);
}
 
// A recursive function to construct Full binary tree
// from pre[] and preM[]. preIndex is used to keep
// track of index in pre[]. l is low index and h is high
//index for the current subarray in preM[]
static Node conBinaryTreeUtil(int []pre, int []preM,
                    INT preIndex, int l, int h, int size)
{
    // Base case
    if (preIndex.a >= size || l > h)
        return null;
 
    // The first node in preorder traversal is root.
    // So take the node at preIndex from preorder and
    // make it root, and increment preIndex
    Node root = newNode(pre[preIndex.a]);
        ++(preIndex.a);
 
    // If the current subarray has only one element,
    // no need to recur
    if (l == h)
        return root;
     
    // Search the next element of pre[] in preM[]
    int i;
    for (i = l; i <= h; ++i)
        if (pre[preIndex.a] == preM[i])
            break;
 
    // construct left and right subtrees recursively
    if (i <= h)
    {
        root.left = conBinaryTreeUtil (pre, preM,
                                    preIndex, i, h, size);
        root.right = conBinaryTreeUtil (pre, preM,
                                preIndex, l + 1, i - 1, size);
    }
 
    // return root
    return root;    
}
 
// function to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
static void conBinaryTree(Node root,int []pre,
                        int []preMirror, int size)
{
    INT preIndex = new INT(0);
    int preMIndex = 0;
 
    root = conBinaryTreeUtil(pre,preMirror,
                            preIndex, 0, size - 1, size);
 
    printInorder(root);
}
 
// Driver code
public static void Main(String []args)
{
    int []preOrder = {1,2,4,5,3,6,7};
    int []preOrderMirror = {1,3,7,6,2,5,4};
 
    int size = preOrder.Length;
 
    Node root = new Node();
 
    conBinaryTree(root,preOrder,preOrderMirror,size);
}
}
 
/* This code is contributed by PrinciRaj1992 */


Javascript


输出:

4 2 5 1 6 3 7 
  • 方法二:仔细观察,镜像树的前序遍历的逆序就是原树的后序遍历。我们可以以与上述类似的方式从给定的前序和后序遍历构造树。您可以参考这篇文章,了解如何从给定的前序和后序遍历构造完整的二叉树。