从给定的父数组表示构造二叉树
给定一个表示树的数组,数组索引是树节点中的值,数组值给出该特定索引(或节点)的父节点。根节点索引的值将始终为 -1,因为根没有父节点。从这个给定的表示构造给定二叉树的标准链接表示。
例子:
Input: parent[] = {1, 5, 5, 2, 2, -1, 3}
Output: root of below tree
5
/ \
1 2
/ / \
0 3 4
/
6
Explanation:
Index of -1 is 5. So 5 is root.
5 is present at indexes 1 and 2. So 1 and 2 are
children of 5.
1 is present at index 0, so 0 is child of 1.
2 is present at indexes 3 and 4. So 3 and 4 are
children of 2.
3 is present at index 6, so 6 is child of 3.
Input: parent[] = {-1, 0, 0, 1, 1, 3, 5};
Output: root of below tree
0
/ \
1 2
/ \
3 4
/
5
/
6
预期的时间复杂度为 O(n),其中 n 是给定数组中的元素数。
我们强烈建议您最小化您的浏览器并首先自己尝试。
递归构造的简单解决方案,首先搜索当前根,然后递归找到找到的索引(最多可以有两个索引)并使它们成为根的左右子树。该解决方案需要 O(n 2 ),因为我们必须线性搜索每个节点。
一个有效的解决方案可以在 O(n) 时间内解决上述问题。这个想法是使用额外的空间。数组 created[0..n-1] 用于跟踪创建的节点。
创建树(父[],n)
- 创建一个指针数组,说 created[0..n-1]。如果未创建索引 i 的节点,则 created[i] 的值为 NULL,否则 value 是指向已创建节点的指针。
- 对给定数组的每个索引 i 执行以下操作
createNode(父,我,创建)
createNode(父[],我,创建[])
- 如果 created[i] 不为 NULL,则节点已经创建。所以回来。
- 创建一个值为“i”的新节点。
- 如果 parent[i] 为 -1(i 为 root),则将创建的节点设为 root 并返回。
- 检查是否创建了“i”的父级(我们可以通过检查 created[parent[i]] 是否为 NULL 来检查。
- 如果没有创建父级,则为父级递归并首先创建父级。
- 设指向父节点的指针为 p。如果 p->left 为 NULL,则将新节点设为左子节点。否则将新节点设为父节点的右子节点。
以下是上述想法的 C++ 实现。
C++
// C++ program to construct a Binary Tree from parent array
#include
using namespace std;
// A tree node
struct Node
{
int key;
struct Node *left, *right;
};
// Utility function to create new Node
Node *newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
// Creates a node with key as 'i'. If i is root, then it changes
// root. If parent of i is not created, then it creates parent first
void createNode(int parent[], int i, Node *created[], Node **root)
{
// If this node is already created
if (created[i] != NULL)
return;
// Create a new node and set created[i]
created[i] = newNode(i);
// If 'i' is root, change root pointer and return
if (parent[i] == -1)
{
*root = created[i];
return;
}
// If parent is not created, then create parent first
if (created[parent[i]] == NULL)
createNode(parent, parent[i], created, root);
// Find parent pointer
Node *p = created[parent[i]];
// If this is first child of parent
if (p->left == NULL)
p->left = created[i];
else // If second child
p->right = created[i];
}
// Creates tree from parent[0..n-1] and returns root of the created tree
Node *createTree(int parent[], int n)
{
// Create an array created[] to keep track
// of created nodes, initialize all entries
// as NULL
Node *created[n];
for (int i=0; ileft);
cout << root->key << " ";
inorder(root->right);
}
}
// Driver method
int main()
{
int parent[] = {-1, 0, 0, 1, 1, 3, 5};
int n = sizeof parent / sizeof parent[0];
Node *root = createTree(parent, n);
cout << "Inorder Traversal of constructed tree\n";
inorder(root);
newLine();
}
Java
// Java program to construct a binary tree from parent array
// A binary tree node
class Node
{
int key;
Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class BinaryTree
{
Node root;
// Creates a node with key as 'i'. If i is root, then it changes
// root. If parent of i is not created, then it creates parent first
void createNode(int parent[], int i, Node created[])
{
// If this node is already created
if (created[i] != null)
return;
// Create a new node and set created[i]
created[i] = new Node(i);
// If 'i' is root, change root pointer and return
if (parent[i] == -1)
{
root = created[i];
return;
}
// If parent is not created, then create parent first
if (created[parent[i]] == null)
createNode(parent, parent[i], created);
// Find parent pointer
Node p = created[parent[i]];
// If this is first child of parent
if (p.left == null)
p.left = created[i];
else // If second child
p.right = created[i];
}
/* Creates tree from parent[0..n-1] and returns root of
the created tree */
Node createTree(int parent[], int n)
{
// Create an array created[] to keep track
// of created nodes, initialize all entries
// as NULL
Node[] created = new Node[n];
for (int i = 0; i < n; i++)
created[i] = null;
for (int i = 0; i < n; i++)
createNode(parent, i, created);
return root;
}
//For adding new line in a program
void newLine()
{
System.out.println("");
}
// Utility function to do inorder traversal
void inorder(Node node)
{
if (node != null)
{
inorder(node.left);
System.out.print(node.key + " ");
inorder(node.right);
}
}
// Driver method
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
int parent[] = new int[]{-1, 0, 0, 1, 1, 3, 5};
int n = parent.length;
Node node = tree.createTree(parent, n);
System.out.println("Inorder traversal of constructed tree ");
tree.inorder(node);
tree.newLine();
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Python implementation to construct a Binary Tree from
# parent array
# A node structure
class Node:
# A utility function to create a new node
def __init__(self, key):
self.key = key
self.left = None
self.right = None
""" Creates a node with key as 'i'. If i is root,then
it changes root. If parent of i is not created, then
it creates parent first
"""
def createNode(parent, i, created, root):
# If this node is already created
if created[i] is not None:
return
# Create a new node and set created[i]
created[i] = Node(i)
# If 'i' is root, change root pointer and return
if parent[i] == -1:
root[0] = created[i] # root[0] denotes root of the tree
return
# If parent is not created, then create parent first
if created[parent[i]] is None:
createNode(parent, parent[i], created, root )
# Find parent pointer
p = created[parent[i]]
# If this is first child of parent
if p.left is None:
p.left = created[i]
# If second child
else:
p.right = created[i]
# Creates tree from parent[0..n-1] and returns root of the
# created tree
def createTree(parent):
n = len(parent)
# Create and array created[] to keep track
# of created nodes, initialize all entries as None
created = [None for i in range(n+1)]
root = [None]
for i in range(n):
createNode(parent, i, created, root)
return root[0]
#Inorder traversal of tree
def inorder(root):
if root is not None:
inorder(root.left)
print (root.key,end=" ")
inorder(root.right)
# Driver Method
parent = [-1, 0, 0, 1, 1, 3, 5]
root = createTree(parent)
print ("Inorder Traversal of constructed tree")
inorder(root)
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
C#
// C# program to construct a binary
// tree from parent array
using System;
// A binary tree node
public class Node
{
public int key;
public Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class GFG
{
public Node root;
// Creates a node with key as 'i'.
// If i is root, then it changes
// root. If parent of i is not created,
// then it creates parent first
public virtual void createNode(int[] parent,
int i, Node[] created)
{
// If this node is already created
if (created[i] != null)
{
return;
}
// Create a new node and set created[i]
created[i] = new Node(i);
// If 'i' is root, change root
// pointer and return
if (parent[i] == -1)
{
root = created[i];
return;
}
// If parent is not created, then
// create parent first
if (created[parent[i]] == null)
{
createNode(parent, parent[i], created);
}
// Find parent pointer
Node p = created[parent[i]];
// If this is first child of parent
if (p.left == null)
{
p.left = created[i];
}
else // If second child
{
p.right = created[i];
}
}
/* Creates tree from parent[0..n-1]
and returns root of the created tree */
public virtual Node createTree(int[] parent, int n)
{
// Create an array created[] to
// keep track of created nodes,
// initialize all entries as NULL
Node[] created = new Node[n];
for (int i = 0; i < n; i++)
{
created[i] = null;
}
for (int i = 0; i < n; i++)
{
createNode(parent, i, created);
}
return root;
}
// For adding new line in a program
public virtual void newLine()
{
Console.WriteLine("");
}
// Utility function to do inorder traversal
public virtual void inorder(Node node)
{
if (node != null)
{
inorder(node.left);
Console.Write(node.key + " ");
inorder(node.right);
}
}
// Driver Code
public static void Main(string[] args)
{
GFG tree = new GFG();
int[] parent = new int[]{-1, 0, 0, 1, 1, 3, 5};
int n = parent.Length;
Node node = tree.createTree(parent, n);
Console.WriteLine("Inorder traversal of " +
"constructed tree ");
tree.inorder(node);
tree.newLine();
}
}
// This code is contributed by Shrikant13
Javascript
输出:
Inorder Traversal of constructed tree
6 5 3 1 4 0 2