📌  相关文章
📜  从给定的父数组表示构造二叉树

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

从给定的父数组表示构造二叉树

给定一个表示树的数组,数组索引是树节点中的值,数组值给出该特定索引(或节点)的父节点。根节点索引的值将始终为 -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)

  1. 创建一个指针数组,说 created[0..n-1]。如果未创建索引 i 的节点,则 created[i] 的值为 NULL,否则 value 是指向已创建节点的指针。
  2. 对给定数组的每个索引 i 执行以下操作
    createNode(父,我,创建)

createNode(父[],我,创建[])

  1. 如果 created[i] 不为 NULL,则节点已经创建。所以回来。
  2. 创建一个值为“i”的新节点。
  3. 如果 parent[i] 为 -1(i 为 root),则将创建的节点设为 root 并返回。
  4. 检查是否创建了“i”的父级(我们可以通过检查 created[parent[i]] 是否为 NULL 来检查。
  5. 如果没有创建父级,则为父级递归并首先创建父级。
  6. 设指向父节点的指针为 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