Saltar al contenido

imprimir nivel de árbol binario por nivel en Python

No dejes de divulgar nuestra página y códigos con otro, apóyanos para ampliar nuestra comunidad.

Solución:

Aquí está mi intento, usando la recursividad y haciendo un seguimiento del tamaño de cada nodo y el tamaño de los niños.

class BstNode:

    def __init__(self, key):
        self.key = key
        self.right = None
        self.left = None

    def insert(self, key):
        if self.key == key:
            return
        elif self.key < key:
            if self.right is None:
                self.right = BstNode(key)
            else:
                self.right.insert(key)
        else: # self.key > key
            if self.left is None:
                self.left = BstNode(key)
            else:
                self.left.insert(key)

    def display(self):
        lines, *_ = self._display_aux()
        for line in lines:
            print(line)

    def _display_aux(self):
        """Returns list of strings, width, height, and horizontal coordinate of the root."""
        # No child.
        if self.right is None and self.left is None:
            line = '%s' % self.key
            width = len(line)
            height = 1
            middle = width // 2
            return [line], width, height, middle

        # Only left child.
        if self.right is None:
            lines, n, p, x = self.left._display_aux()
            s = '%s' % self.key
            u = len(s)
            first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s
            second_line = x * ' ' + '/' + (n - x - 1 + u) * ' '
            shifted_lines = [line + u * ' ' for line in lines]
            return [first_line, second_line] + shifted_lines, n + u, p + 2, n + u // 2

        # Only right child.
        if self.left is None:
            lines, n, p, x = self.right._display_aux()
            s = '%s' % self.key
            u = len(s)
            first_line = s + x * '_' + (n - x) * ' '
            second_line = (u + x) * ' ' + '\' + (n - x - 1) * ' '
            shifted_lines = [u * ' ' + line for line in lines]
            return [first_line, second_line] + shifted_lines, n + u, p + 2, u // 2

        # Two children.
        left, n, p, x = self.left._display_aux()
        right, m, q, y = self.right._display_aux()
        s = '%s' % self.key
        u = len(s)
        first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s + y * '_' + (m - y) * ' '
        second_line = x * ' ' + '/' + (n - x - 1 + u + y) * ' ' + '\' + (m - y - 1) * ' '
        if p < q:
            left += [n * ' '] * (q - p)
        elif q < p:
            right += [m * ' '] * (p - q)
        zipped_lines = zip(left, right)
        lines = [first_line, second_line] + [a + u * ' ' + b for a, b in zipped_lines]
        return lines, n + m + u, max(p, q) + 2, n + u // 2


import random

b = BstNode(50)
for _ in range(50):
    b.insert(random.randint(0, 100))
b.display()

Salida de ejemplo:

                              __50_________________________________________ 
                             /                                             
    ________________________43_                   ________________________99
   /                                            /                          
  _9_                         48    ____________67_____________________     
 /                                /                                       
 3  11_________                   54___                         ______96_   
/                                                           /           
0 8       ____26___________           61___           ________88___     97  
         /                          /              /                     
        14_             __42        56    64_       75_____       92_       
       /              /                 /        /            /         
      13  16_         33_               63  65_   72      81_   90  94      
                    /                                 /                 
            25    __31  41                    66        80  87              
                 /                                     /                    
                28_                                   76                    
                                                                           
                  29                                                        

Lo que está buscando es un recorrido que priorice la amplitud, que le permite atravesar un árbol nivel por nivel. Básicamente, usa una cola para realizar un seguimiento de los nodos que necesita visitar, agregando niños al espalda de la cola a medida que avanza (en lugar de agregarlos a la parte delantera de una pila). Primero haz que funcione.

Después de hacer eso, puede averiguar cuántos niveles tiene el árbol (log2(node_count) + 1) y utilícelo para estimar los espacios en blanco. Si desea obtener el espacio en blanco exactamente correcto, puede usar otras estructuras de datos para realizar un seguimiento de cuántos espacios necesita por nivel. Sin embargo, una estimación inteligente utilizando el número de nodos y niveles debería ser suficiente.

Mejoré la respuesta de Prashant Shukla para imprimir los nodos en el mismo nivel en la misma línea sin espacios.

class Node(object):
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right

    def __str__(self):
        return str(self.value)


def traverse(root):
    current_level = [root]
    while current_level:
        print(' '.join(str(node) for node in current_level))
        next_level = list()
        for n in current_level:
            if n.left:
                next_level.append(n.left)
            if n.right:
                next_level.append(n.right)
        current_level = next_level

t = Node(1, Node(2, Node(4, Node(7)), Node(9)), Node(3, Node(5), Node(6)))

traverse(t)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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