从 Inorder 和 Level 顺序遍历构造一棵树 |设置 1
给定二叉树的顺序和级别顺序遍历,构造二叉树。下面是一个例子来说明这个问题。
Input: Two arrays that represent Inorder
and level order traversals of a
Binary Tree
in[] = {4, 8, 10, 12, 14, 20, 22};
level[] = {20, 8, 22, 4, 12, 10, 14};
Output: Construct the tree represented
by the two arrays.
For the above two arrays, the
constructed tree is shown in
the diagram on right side
可以将以下帖子视为此的先决条件。
从给定的中序和前序遍历构造树
让我们考虑上面的例子。
in[] = {4, 8, 10, 12, 14, 20, 22};
级别[] = {20, 8, 22, 4, 12, 10, 14};
在 Levelorder 序列中,第一个元素是树的根。所以我们知道'20'是给定序列的根。通过Inorder序列搜索'20',我们可以发现'20'左侧的所有元素都在左子树中,右侧的元素都在右子树中。所以我们现在知道下面的结构。
20
/ \
/ \
{4,8,10,12,14} {22}
让我们将 {4,8,10,12,14} 称为中序遍历中的左子数组,将 {22} 称为中序遍历中的右子数组。
在层序遍历中,左右子树的键是不连续的。因此,我们从级别顺序遍历中提取所有节点,这些节点位于中序遍历的左子数组中。为了构造根的左子树,我们对从层序遍历和中序遍历的左子数组中提取的元素进行递归。在上面的示例中,我们重复以下两个数组。
// Recur for following arrays to construct the left subtree
In[] = {4, 8, 10, 12, 14}
level[] = {8, 4, 12, 10, 14}
同样,我们递归跟踪两个数组并构造右子树。
// Recur for following arrays to construct the right subtree
In[] = {22}
level[] = {22}
以下是上述方法的实现:
C++
/* program to construct tree using inorder and levelorder
* traversals */
#include
using namespace std;
/* A binary tree node */
struct Node {
int key;
struct Node *left, *right;
};
/* Function to find index of value in arr[start...end] */
int search(int arr[], int strt, int end, int value)
{
for (int i = strt; i <= end; i++)
if (arr[i] == value)
return i;
return -1;
}
// n is size of level[], m is size of in[] and m < n. This
// function extracts keys from level[] which are present in
// in[]. The order of extracted keys must be maintained
int* extrackKeys(int in[], int level[], int m, int n)
{
int *newlevel = new int[m], j = 0;
for (int i = 0; i < n; i++)
if (search(in, 0, m - 1, level[i]) != -1)
newlevel[j] = level[i], j++;
return newlevel;
}
/* function that allocates a new node with the given key */
Node* newNode(int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}
/* Recursive function to construct binary tree of size n
from Inorder traversal in[] and Level Order traversal
level[]. inStrt and inEnd are start and end indexes of
array in[] Initial values of inStrt and inEnd should be 0
and n -1. The function doesn't do any error checking for
cases where inorder and levelorder do not form a tree */
Node* buildTree(int in[], int level[], int inStrt,
int inEnd, int n)
{
// If start index is more than the end index
if (inStrt > inEnd)
return NULL;
/* The first node in level order traversal is root */
Node* root = newNode(level[0]);
/* If this node has no children then return */
if (inStrt == inEnd)
return root;
/* Else find the index of this node in Inorder traversal
*/
int inIndex = search(in, inStrt, inEnd, root->key);
// Extract left subtree keys from level order traversal
int* llevel = extrackKeys(in, level, inIndex, n);
// Extract right subtree keys from level order traversal
int* rlevel
= extrackKeys(in + inIndex + 1, level, n - 1, n);
/* construct left and right subtrees */
root->left = buildTree(in, llevel, inStrt, inIndex - 1,
inIndex - inStrt);
root->right = buildTree(in, rlevel, inIndex + 1, inEnd,
inEnd - inIndex);
// Free memory to avoid memory leak
delete[] llevel;
delete[] rlevel;
return root;
}
/* utility function to print inorder traversal of binary
* tree */
void printInorder(Node* node)
{
if (node == NULL)
return;
printInorder(node->left);
cout << node->key << " ";
printInorder(node->right);
}
/* Driver program to test above functions */
int main()
{
int in[] = { 4, 8, 10, 12, 14, 20, 22 };
int level[] = { 20, 8, 22, 4, 12, 10, 14 };
int n = sizeof(in) / sizeof(in[0]);
Node* root = buildTree(in, level, 0, n - 1, n);
/* Let us test the built tree by printing Inorder
* traversal */
cout << "Inorder traversal of the constructed tree is "
"\n";
printInorder(root);
return 0;
}
Java
// Java program to construct a tree from level order and
// and inorder traversal
// A binary tree node
class Node {
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
public void setLeft(Node left) { this.left = left; }
public void setRight(Node right) { this.right = right; }
}
class Tree {
Node root;
Node buildTree(int in[], int level[])
{
Node startnode = null;
return constructTree(startnode, level, in, 0,
in.length - 1);
}
Node constructTree(Node startNode, int[] levelOrder,
int[] inOrder, int inStart,
int inEnd)
{
// if start index is more than end index
if (inStart > inEnd)
return null;
if (inStart == inEnd)
return new Node(inOrder[inStart]);
boolean found = false;
int index = 0;
// it represents the index in inOrder array of
// element that appear first in levelOrder array.
for (int i = 0; i < levelOrder.length - 1; i++) {
int data = levelOrder[i];
for (int j = inStart; j < inEnd; j++) {
if (data == inOrder[j]) {
startNode = new Node(data);
index = j;
found = true;
break;
}
}
if (found == true)
break;
}
// elements present before index are part of left
// child of startNode. elements present after index
// are part of right child of startNode.
startNode.setLeft(
constructTree(startNode, levelOrder, inOrder,
inStart, index - 1));
startNode.setRight(
constructTree(startNode, levelOrder, inOrder,
index + 1, inEnd));
return startNode;
}
/* Utility function to print inorder traversal of 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 the above functions
public static void main(String args[])
{
Tree tree = new Tree();
int in[] = new int[] { 4, 8, 10, 12, 14, 20, 22 };
int level[]
= new int[] { 20, 8, 22, 4, 12, 10, 14 };
int n = in.length;
Node node = tree.buildTree(in, level);
/* Let us test the built tree by printing Inorder
* traversal */
System.out.print(
"Inorder traversal of the constructed tree is ");
tree.printInorder(node);
}
}
// This code has been contributed by Mayank Jaiswal
Python3
# Python program to construct tree using
# inorder and level order traversals
# A binary tree node
class Node:
# Constructor to create a new node
def __init__(self, key):
self.data = key
self.left = None
self.right = None
"""Recursive function to construct binary tree of size n from
Inorder traversal ino[] and Level Order traversal level[].
The function doesn't do any error checking for cases
where inorder and levelorder do not form a tree """
def buildTree(level, ino):
# If ino array is not empty
if ino:
# Check if that element exist in level order
for i in range(0, len(level)):
if level[i] in ino:
# Create a new node with
# the matched element
node = Node(level[i])
# Get the index of the matched element
# in level order array
io_index = ino.index(level[i])
break
# Construct left and right subtree
node.left = buildTree(level, ino[0:io_index])
node.right = buildTree(level, ino[io_index + 1:len(ino)])
return node
else:
return None
def printInorder(node):
if node is None:
return
# first recur on left child
printInorder(node.left)
# then print the data of node
print(node.data, end=" ")
# now recur on right child
printInorder(node.right)
# Driver code
levelorder = [20, 8, 22, 4, 12, 10, 14]
inorder = [4, 8, 10, 12, 14, 20, 22]
ino_len = len(inorder)
root = buildTree(levelorder, inorder)
# Let us test the build tree by
# printing Inorder traversal
print("Inorder traversal of the constructed tree is")
printInorder(root)
# This code is contributed by 'Vaibhav Kumar'
C#
// C# program to construct a tree from
// level order and and inorder traversal
using System;
// A binary tree node
public class Node {
public int data;
public Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
public virtual Node Left
{
set { this.left = value; }
}
public virtual Node Right
{
set { this.right = value; }
}
}
class GFG {
public Node root;
public virtual Node buildTree(int[] arr, int[] level)
{
Node startnode = null;
return constructTree(startnode, level, arr, 0,
arr.Length - 1);
}
public virtual Node
constructTree(Node startNode, int[] levelOrder,
int[] inOrder, int inStart, int inEnd)
{
// if start index is more than end index
if (inStart > inEnd) {
return null;
}
if (inStart == inEnd) {
return new Node(inOrder[inStart]);
}
bool found = false;
int index = 0;
// it represents the index in inOrder
// array of element that appear first
// in levelOrder array.
for (int i = 0; i < levelOrder.Length - 1; i++) {
int data = levelOrder[i];
for (int j = inStart; j < inEnd; j++) {
if (data == inOrder[j]) {
startNode = new Node(data);
index = j;
found = true;
break;
}
}
if (found == true) {
break;
}
}
// elements present before index are
// part of left child of startNode.
// elements present after index are
// part of right child of startNode.
startNode.Left
= constructTree(startNode, levelOrder, inOrder,
inStart, index - 1);
startNode.Right
= constructTree(startNode, levelOrder, inOrder,
index + 1, inEnd);
return startNode;
}
/* Utility function to print inorder
traversal of binary tree */
public virtual void printInorder(Node node)
{
if (node == null) {
return;
}
printInorder(node.left);
Console.Write(node.data + " ");
printInorder(node.right);
}
// Driver Code
public static void Main(string[] args)
{
GFG tree = new GFG();
int[] arr = new int[] { 4, 8, 10, 12, 14, 20, 22 };
int[] level
= new int[] { 20, 8, 22, 4, 12, 10, 14 };
int n = arr.Length;
Node node = tree.buildTree(arr, level);
/* Let us test the built tree by
printing Inorder traversal */
Console.Write("Inorder traversal of the "
+ "constructed tree is "
+ "\n");
tree.printInorder(node);
}
}
// This code is contributed by Shrikant13
Javascript
输出:
Inorder traversal of the constructed tree is
4 8 10 12 14 20 22