Representación del árbol del hijo izquierdo y del hermano derecho

Un árbol n-ario en informática es una colección de Nodes normalmente representados jerárquicamente de la siguiente manera.  

  1. El árbol comienza en el Node raíz.
  2. Cada Node del árbol contiene una lista de referencias a sus Nodes secundarios.
  3. El número de hijos que tiene un Node es menor o igual que n.

Una representación típica del árbol n-ario utiliza una array de n referencias (o punteros) para almacenar elementos secundarios (tenga en cuenta que n es un límite superior en el número de elementos secundarios). ¿Podemos hacerlo mejor? la idea de la representación Izquierda-Hijo Derecha-Hermano es almacenar solo dos punteros en cada Node.
 

Representación del hermano izquierdo-hijo derecho

Es una representación diferente de un árbol n-ario donde en lugar de contener una referencia a todos y cada uno de los Nodes secundarios, un Node contiene solo dos referencias, primero una referencia a su primer hijo y la otra a su siguiente hermano inmediato. Esta nueva transformación no solo elimina la necesidad de conocer por adelantado el número de hijos que tiene un Node, sino que también limita el número de referencias a un máximo de dos, lo que facilita mucho la codificación. Una cosa a tener en cuenta es que en la representación anterior, un enlace entre dos Nodes denotaba una relación padre-hijo, mientras que en esta representación un enlace entre dos Nodes puede denotar una relación padre-hijo o una relación hermano-hermano.

Ventajas: 
1. Esta representación ahorra memoria al limitar a dos el número máximo de referencias requeridas por Node. 
2. Es más fácil codificar.

Desventajas: 
1. Las operaciones básicas como buscar/insertar/eliminar tienden a llevar más tiempo porque para encontrar la posición adecuada tendríamos que atravesar todos los hermanos del Node que se busca/inserta/elimina (en el peor de los casos ).
La imagen de la izquierda es la representación normal de un árbol de 6 arios y la de la derecha es su representación correspondiente del hijo izquierdo y el hermano derecho.
 

Fuente de la imagen: https://en.wikipedia.org/wiki/Left-child_right-sibling_binary_tree

Un problema de ejemplo:
ahora veamos un problema e intentemos resolverlo usando las dos representaciones discutidas para mayor claridad.
Dado un árbol genealógico. Encuentre el k-ésimo hijo de algún miembro X en el árbol. 
El usuario ingresa dos cosas. 
1. Un carácter P (que representa al padre cuyo hijo se va a encontrar) 
2. Un número entero k (que representa el número del hijo)
El problema en sí parece bastante sencillo. El único problema aquí es que no se especifica el número máximo de hijos que puede tener un Node, lo que hace que sea bastante complicado construir el árbol.

Ejemplo: 
Considere el siguiente árbol genealógico.
 

Untitled Diagram

Input : A 2
Output : C
In this case, the user wishes to know A's
second child which according to the figure
is C.

Input : F 3
Output : K
Similar to the first case, the user wishes 
to know F's third child which is K.
Método 1 (Almacenamiento de n punteros con cada Node):

En este método, asumimos el número máximo de hijos que puede tener un Node y seguimos adelante. El único problema (obvio) con este método es el límite superior del número de hijos. Si el valor es demasiado bajo, el código fallará en ciertos casos y si el valor es demasiado alto, se desperdiciará innecesariamente una gran cantidad de memoria. 
Si el programador conoce de antemano la estructura del árbol, entonces el límite superior se puede establecer en el número máximo de hijos que tiene un Node en esa estructura en particular. Pero incluso en ese caso, habrá algún desperdicio de memoria (es posible que no todos los Nodes tengan necesariamente el mismo número de hijos, algunos incluso pueden tener menos. Ejemplo: los Nodes hoja no tienen hijos ).

C++

// C++ program to find k-th child of a given
// node using typical representation that uses
// an array of pointers.
#include <iostream>
using namespace std;
 
// Maximum number of children
const int N = 10;
 
class Node
{
public:
    char val;
    Node * child[N];
    Node(char P)
    {
        val = P;
        for (int i=0; i<MAX; i++)
            child[i] = NULL;
    }
};
 
// Traverses given n-ary tree to find K-th
// child of P.
void printKthChild(Node *root, char P, int k)
{
    // If P is current root
    if (root->val == P)
    {
         if (root->child[k-1] == NULL)
             cout << "Error : Does not exist\n";
         else
             cout << root->child[k-1]->val << endl;
    }
 
    // If P lies in a subtree
    for (int i=0; i<N; i++)
        if (root->child[i] != NULL)
            printKthChild(root->child[i], P, k);
}
 
// Driver code
int main()
{
    Node *root = new Node('A');
    root->child[0] = new Node('B');
    root->child[1] = new Node('C');
    root->child[2] = new Node('D');
    root->child[3] = new Node('E');
    root->child[0]->child[0] = new Node('F');
    root->child[0]->child[1] = new Node('G');
    root->child[2]->child[0] = new Node('H');
    root->child[0]->child[0]->child[0] = new Node('I');
    root->child[0]->child[0]->child[1] = new Node('J');
    root->child[0]->child[0]->child[2] = new Node('K');
    root->child[2]->child[0]->child[0] = new Node('L');
    root->child[2]->child[0]->child[1] = new Node('M');
 
    // Print F's 2nd child
    char P = 'F';
    cout << "F's second child is : ";
    printKthChild(root, P, 2);
 
    P = 'A';
    cout << "A's seventh child is : ";
    printKthChild(root, P, 7);
    return 0;
}

Java

// Java program to find k-th child
// of a given node using typical
// representation that uses
// an array of pointers.
class GFG
{
 
    // Maximum number of children
    static int N = 10;
 
    static class Node
    {
        char val;
        Node[] child = new Node[N];
 
        Node(char P)
        {
            val = P;
            for (int i = 0; i < N; i++)
                child[i] = null;
        }
    };
 
    // Traverses given n-ary tree to
    // find K-th child of P.
    static void printKthChild(Node root,
                              char P, int k)
    {
        // If P is current root
        if (root.val == P)
        {
            if (root.child[k - 1] == null)
                System.out.print("Error : Does not exist\n");
            else
                System.out.print(root.child[k - 1].val + "\n");
        }
 
        // If P lies in a subtree
        for (int i = 0; i < N; i++)
            if (root.child[i] != null)
                printKthChild(root.child[i], P, k);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Node root = new Node('A');
        root.child[0] = new Node('B');
        root.child[1] = new Node('C');
        root.child[2] = new Node('D');
        root.child[3] = new Node('E');
        root.child[0].child[0] = new Node('F');
        root.child[0].child[1] = new Node('G');
        root.child[2].child[0] = new Node('H');
        root.child[0].child[0].child[0] = new Node('I');
        root.child[0].child[0].child[1] = new Node('J');
        root.child[0].child[0].child[2] = new Node('K');
        root.child[2].child[0].child[0] = new Node('L');
        root.child[2].child[0].child[1] = new Node('M');
 
        // Print F's 2nd child
        char P = 'F';
        System.out.print("F's second child is : ");
        printKthChild(root, P, 2);
 
        P = 'A';
        System.out.print("A's seventh child is : ");
        printKthChild(root, P, 7);
    }
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 program to find k-th child of a given
# node using typical representation that uses
# an array of pointers.
 
# Maximum number of children
N = 10
 
class Node:
    def __init__(self , P):
        self.val = P
        self.child = []
        for i in range(10):
            self.child.append(None)
     
# Traverses given n-ary tree to find K-th
# child of P.
def printKthChild(root, P, k):
 
    # If P is current root
    if (root.val == P):
     
        if (root.child[k - 1] == None):
            print("Error : Does not exist")
        else:
            print( root.child[k - 1].val )
     
    # If P lies in a subtree
    for i in range(N) :
        if (root.child[i] != None):
            printKthChild(root.child[i], P, k)
 
# Driver code
 
root = Node('A')
root.child[0] = Node('B')
root.child[1] = Node('C')
root.child[2] = Node('D')
root.child[3] = Node('E')
root.child[0].child[0] = Node('F')
root.child[0].child[1] = Node('G')
root.child[2].child[0] = Node('H')
root.child[0].child[0].child[0] = Node('I')
root.child[0].child[0].child[1] = Node('J')
root.child[0].child[0].child[2] = Node('K')
root.child[2].child[0].child[0] = Node('L')
root.child[2].child[0].child[1] = Node('M')
 
# Print F's 2nd child
P = 'F'
print( "F's second child is : ")
printKthChild(root, P, 2)
 
P = 'A'
print( "A's seventh child is : ")
printKthChild(root, P, 7)
 
# This code is contributed by Arnab Kundu

C#

// C# program to find k-th child
// of a given node using typical
// representation that uses
// an array of pointers.
using System;
 
class GFG
{
 
    // Maximum number of children
    static int N = 10;
 
    class Node
    {
        public char val;
        public Node[] child = new Node[N];
 
        public Node(char P)
        {
            val = P;
            for (int i = 0; i < N; i++)
                child[i] = null;
        }
    };
 
    // Traverses given n-ary tree to
    // find K-th child of P.
    static void printKthChild(Node root,
                              char P, int k)
    {
        // If P is current root
        if (root.val == P)
        {
            if (root.child[k - 1] == null)
                Console.Write("Error : Does not exist\n");
            else
                Console.Write(root.child[k - 1].val + "\n");
        }
 
        // If P lies in a subtree
        for (int i = 0; i < N; i++)
            if (root.child[i] != null)
                printKthChild(root.child[i], P, k);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Node root = new Node('A');
        root.child[0] = new Node('B');
        root.child[1] = new Node('C');
        root.child[2] = new Node('D');
        root.child[3] = new Node('E');
        root.child[0].child[0] = new Node('F');
        root.child[0].child[1] = new Node('G');
        root.child[2].child[0] = new Node('H');
        root.child[0].child[0].child[0] = new Node('I');
        root.child[0].child[0].child[1] = new Node('J');
        root.child[0].child[0].child[2] = new Node('K');
        root.child[2].child[0].child[0] = new Node('L');
        root.child[2].child[0].child[1] = new Node('M');
 
        // Print F's 2nd child
        char P = 'F';
        Console.Write("F's second child is : ");
        printKthChild(root, P, 2);
 
        P = 'A';
        Console.Write("A's seventh child is : ");
        printKthChild(root, P, 7);
    }
}
 
// This code is contributed by Rajput-Ji

Javascript

<script>
  
// Javascript program to find k-th child of a
// given node using typical representation that
// uses an array of pointers.Maximum number of children
var N = 10;
class Node
{
    constructor(P)
    {
        this.val = P;
        this.child = Array(N).fill(null);
    }
};
 
// Traverses given n-ary tree to
// find K-th child of P.
function printKthChild(root, P, k)
{
     
    // If P is current root
    if (root.val == P)
    {
        if (root.child[k - 1] == null)
            document.write("Error : Does not exist<br>");
        else
            document.write(root.child[k - 1].val + "<br>");
    }
     
    // If P lies in a subtree
    for(var i = 0; i < N; i++)
        if (root.child[i] != null)
            printKthChild(root.child[i], P, k);
}
 
// Driver code
var root = new Node('A');
root.child[0] = new Node('B');
root.child[1] = new Node('C');
root.child[2] = new Node('D');
root.child[3] = new Node('E');
root.child[0].child[0] = new Node('F');
root.child[0].child[1] = new Node('G');
root.child[2].child[0] = new Node('H');
root.child[0].child[0].child[0] = new Node('I');
root.child[0].child[0].child[1] = new Node('J');
root.child[0].child[0].child[2] = new Node('K');
root.child[2].child[0].child[0] = new Node('L');
root.child[2].child[0].child[1] = new Node('M');
 
// Print F's 2nd child
var P = 'F';
document.write("F's second child is : ");
printKthChild(root, P, 2);
P = 'A';
document.write("A's seventh child is : ");
printKthChild(root, P, 7);
 
// This code is contributed by noob2000
 
</script>

Producción: 
 

F's second child is : J
A's seventh child is : Error : Does not exist

En el árbol anterior, si hubiera habido un Node que tuviera, digamos, 15 hijos, entonces este código habría dado una falla de segmentación. 
 

Método 2: (Representación del hermano derecho del hijo izquierdo)

En este método, cambiamos la estructura del árbol genealógico. En el árbol estándar, cada Node padre está conectado a todos sus hijos. Aquí, como se discutió anteriormente, en lugar de que cada Node almacene punteros a todos sus elementos secundarios, un Node almacenará el puntero a solo uno de sus elementos secundarios. Aparte de esto, el Node también almacenará un puntero a su hermano derecho inmediato.
La imagen de abajo es el equivalente de Left-Child Right-Sibling del ejemplo usado arriba.
 

new

C++

// C++ program to find k-th child of a given
// Node using typical representation that uses
// an array of pointers.
#include <iostream>
using namespace std;
 
// A Node to represent left child right sibling
// representation.
class Node
{
public:
    char val;
    Node *child;
    Node *next;
    Node(char P)
    {
        val = P;
        child = NULL;
        next = NULL;
    }
};
 
// Traverses given n-ary tree to find K-th
// child of P.
void printKthChild(Node *root, char P, int k)
{
    if (root == NULL)
        return;
 
    // If P is present at root itself
    if (root->val == P)
    {
        // Traverse children of root starting
        // from left child
        Node *t = root->child;
        int i = 1;
        while (t != NULL && i < k)
        {
            t = t->next;
            i++;
        }
        if (t == NULL)
            cout << "Error : Does not exist\n";
        else
            cout << t->val << " " << endl;
        return;
 
    }
    printKthChild(root->child, P, k);
    printKthChild(root->next, P, k);
}
 
// Driver code
int main()
{
    Node *root = new Node('A');
    root->child = new Node('B');
    root->child->next = new Node('C');
    root->child->next->next = new Node('D');
    root->child->next->next->next = new Node('E');
    root->child->child = new Node('F');
    root->child->child->next = new Node('G');
    root->child->next->next->child = new Node('H');
    root->child->next->next->child->child = new Node('L');
    root->child->next->next->child->child->next = new Node('M');
    root->child->child->child = new Node('I');
    root->child->child->child->next = new Node('J');
    root->child->child->child->next->next = new Node('K');
 
    // Print F's 2nd child
    char P = 'F';
    cout << "F's second child is : ";
    printKthChild(root, P, 2);
 
    P = 'A';
    cout << "A's seventh child is : ";
    printKthChild(root, P, 7);
    return 0;
}

Java

// Java program to find k-th child of a given
// Node using typical representation that uses
// an array of pointers.
class GFG
{
 
    // A Node to represent left child
    // right sibling representation.
    static class Node
    {
        char val;
        Node child;
        Node next;
        Node(char P)
        {
            val = P;
            child = null;
            next = null;
        }
    };
 
    // Traverses given n-ary tree to find K-th
    // child of P.
    static void printKthChild(Node root, char P, int k)
    {
        if (root == null)
            return;
 
        // If P is present at root itself
        if (root.val == P)
        {
            // Traverse children of root starting
            // from left child
            Node t = root.child;
            int i = 1;
            while (t != null && i < k)
            {
                t = t.next;
                i++;
            }
            if (t == null)
                System.out.print("Error : Does not exist\n");
            else
                System.out.print(t.val + " " + "\n");
            return;
        }
        printKthChild(root.child, P, k);
        printKthChild(root.next, P, k);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Node root = new Node('A');
        root.child = new Node('B');
        root.child.next = new Node('C');
        root.child.next.next = new Node('D');
        root.child.next.next.next = new Node('E');
        root.child.child = new Node('F');
        root.child.child.next = new Node('G');
        root.child.next.next.child = new Node('H');
        root.child.next.next.child.child = new Node('L');
        root.child.next.next.child.child.next = new Node('M');
        root.child.child.child = new Node('I');
        root.child.child.child.next = new Node('J');
        root.child.child.child.next.next = new Node('K');
 
        // Print F's 2nd child
        char P = 'F';
        System.out.print("F's second child is : ");
        printKthChild(root, P, 2);
 
        P = 'A';
        System.out.print("A's seventh child is : ");
        printKthChild(root, P, 7);
    }
}
 
// This code is contributed by 29AjayKumar

Python3

# Python program to find k-th child of a given
# Node using typical representation that uses
# an array of pointers.
 
# A Node to represent left child
    # right sibling representation.
class Node:
    def __init__(self,P):
        self.val = P
        self.child = None
        self.next = None
 
# Traverses given n-ary tree to find K-th
    # child of P.
def printKthChild(root, P, k):
    if (root == None):
        return
 
    # If P is present at root itself
    if (root.val == P):
        # Traverse children of root starting
        # from left child
        t = root.child
        i = 1
        while (t != None and i < k):
            t = t.next
            i += 1
     
        if (t == None):
            print("Error : Does not exist")
        else:
            print(t.val)
        return
     
    printKthChild(root.child, P, k)
    printKthChild(root.next, P, k)
 
# Driver code
root = Node('A')
root.child = Node('B')
root.child.next = Node('C')
root.child.next.next = Node('D')
root.child.next.next.next = Node('E')
root.child.child = Node('F')
root.child.child.next = Node('G')
root.child.next.next.child = Node('H')
root.child.next.next.child.child = Node('L')
root.child.next.next.child.child.next = Node('M')
root.child.child.child = Node('I')
root.child.child.child.next = Node('J')
root.child.child.child.next.next = Node('K')
 
# Print F's 2nd child
P = 'F'
print("F's second child is :",end=" ")
printKthChild(root, P, 2)
 
P = 'A'
print("A's seventh child is :",end=" ")
printKthChild(root, P, 7)
 
# this code is contributed by shinjanpatra

C#

// C# program to find k-th child of a given
// Node using typical representation that uses
// an array of pointers.
using System;
 
class GFG
{
 
    // A Node to represent left child
    // right sibling representation.
    public class Node
    {
        public char val;
        public Node child;
        public Node next;
        public Node(char P)
        {
            val = P;
            child = null;
            next = null;
        }
    };
 
    // Traverses given n-ary tree to find K-th
    // child of P.
    static void printKthChild(Node root,           
                              char P, int k)
    {
        if (root == null)
            return;
 
        // If P is present at root itself
        if (root.val == P)
        {
            // Traverse children of root starting
            // from left child
            Node t = root.child;
            int i = 1;
            while (t != null && i < k)
            {
                t = t.next;
                i++;
            }
            if (t == null)
                Console.Write("Error : Does not exist\n");
            else
                Console.Write(t.val + " " + "\n");
            return;
        }
        printKthChild(root.child, P, k);
        printKthChild(root.next, P, k);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Node root = new Node('A');
        root.child = new Node('B');
        root.child.next = new Node('C');
        root.child.next.next = new Node('D');
        root.child.next.next.next = new Node('E');
        root.child.child = new Node('F');
        root.child.child.next = new Node('G');
        root.child.next.next.child = new Node('H');
        root.child.next.next.child.child = new Node('L');
        root.child.next.next.child.child.next = new Node('M');
        root.child.child.child = new Node('I');
        root.child.child.child.next = new Node('J');
        root.child.child.child.next.next = new Node('K');
 
        // Print F's 2nd child
        char P = 'F';
        Console.Write("F's second child is : ");
        printKthChild(root, P, 2);
 
        P = 'A';
        Console.Write("A's seventh child is : ");
        printKthChild(root, P, 7);
    }
}
 
// This code is contributed by Rajput-Ji

Javascript

<script>
// Javascript program to find k-th child of a given
// Node using typical representation that uses
// an array of pointers.
 
// A Node to represent left child
    // right sibling representation.
class Node
{
    constructor(P)
    {
        this.val = P;
        this.child = null;
        this.next = null;
    }
}
 
// Traverses given n-ary tree to find K-th
    // child of P.
function printKthChild(root, P, k)
{
    if (root == null)
            return;
  
        // If P is present at root itself
        if (root.val == P)
        {
            // Traverse children of root starting
            // from left child
            let t = root.child;
            let i = 1;
            while (t != null && i < k)
            {
                t = t.next;
                i++;
            }
            if (t == null)
                document.write("Error : Does not exist<br>");
            else
                document.write(t.val + " " + "<br>");
            return;
        }
        printKthChild(root.child, P, k);
        printKthChild(root.next, P, k);
}
 
// Driver code
let root = new Node('A');
root.child = new Node('B');
root.child.next = new Node('C');
root.child.next.next = new Node('D');
root.child.next.next.next = new Node('E');
root.child.child = new Node('F');
root.child.child.next = new Node('G');
root.child.next.next.child = new Node('H');
root.child.next.next.child.child = new Node('L');
root.child.next.next.child.child.next = new Node('M');
root.child.child.child = new Node('I');
root.child.child.child.next = new Node('J');
root.child.child.child.next.next = new Node('K');
 
// Print F's 2nd child
let P = 'F';
document.write("F's second child is : ");
printKthChild(root, P, 2);
 
P = 'A';
document.write("A's seventh child is : ");
printKthChild(root, P, 7);
 
// This code is contributed by avanitrachhadiya2155
</script>

Producción: 

F's second child is : J
A's seventh child is : Error : Does not exist

Artículo relacionado: 
Creación de un árbol con representación de hijo izquierdo-hermano derecho

Este artículo es una contribución de Akhil Goel . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *