使用它的前序遍历和镜像树的前序遍历构造完整的二叉树
给定两个表示完整二叉树及其镜像树的前序遍历的数组,我们需要编写一个程序来使用这两个前序遍历来构造二叉树。
完全二叉树是一棵二叉树,其中每个节点都有 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
- 方法二:仔细观察,镜像树的前序遍历的逆序就是原树的后序遍历。我们可以以与上述类似的方式从给定的前序和后序遍历构造树。您可以参考这篇文章,了解如何从给定的前序和后序遍历构造完整的二叉树。