árbol binario -mostrar los elementos de acuerdo con el nivel

votos
6

Esta pregunta se hizo a mí en una entrevista:

Árbol

digamos que tenemos por encima de árbol binario, ¿Cómo puedo producir una salida como la siguiente

2 7 5 2 6 9 5 11 4

Le respondí como puede ser que podemos tener una variable de recuento nivel e imprimir todos los elementos secuencialmente marcando la variable de recuento nivel de cada nodo. Probablemente yo estaba equivocado.

¿alguien puede dar anyidea en cuanto a cómo podemos lograr eso?

Publicado el 14/04/2011 a las 08:07
fuente por usuario
En otros idiomas...                            


7 respuestas

votos
2

El recorrido en su pregunta se llama level-order traversaly esto es cómo se hace (fragmento muy simple / limpia código que encontré).

Es, básicamente, utiliza una cola y el orden de las operaciones se verá algo como esto:

enqueue F
dequeue F
enqueue B G
dequeue B
enqueue A D
dequeue G
enqueue I
dequeue A
dequeue D
enqueue C E
dequeue I
enqueue H
dequeue C
dequeue E
dequeue H

Para este árbol (recta de Wikipedia):
introducir descripción de la imagen aquí

Respondida el 14/04/2011 a las 08:14
fuente por usuario

votos
2

El plazo para que sea de nivel de orden transversal . Wikipedia describe un algoritmo para que el uso de una cola :

levelorder(root) 
  q = empty queue
  q.enqueue(root)
  while not q.empty do
    node := q.dequeue()
    visit(node)
    if node.left ≠ null
      q.enqueue(node.left)
    if node.right ≠ null
      q.enqueue(node.right)
Respondida el 14/04/2011 a las 08:14
fuente por usuario

votos
2

BFS :

std::queue<Node const *> q;
q.push(&root);
while (!q.empty()) {
    Node const *n = q.front();
    q.pop();
    std::cout << n->data << std::endl;
    if (n->left)
        q.push(n->left);
    if (n->right)
        q.push(n->right);
}

profundización iterativa también funcionaría y ahorra el uso de memoria, pero a expensas de tiempo de cálculo.

Respondida el 14/04/2011 a las 08:16
fuente por usuario

votos
6

Es necesario hacer un primer recorrido de amplitud del árbol. Aquí se describe como sigue:

Primero en amplitud de recorrido: primero en profundidad no es el único camino a seguir a través de los elementos de un árbol. Otra forma es ir a través de ellos de nivel por nivel.

Por ejemplo, existe cada elemento en un nivel determinado (o profundidad) en el árbol:

    tree
      ----
       j         <-- level 0
     /   \
    f      k     <-- level 1
  /   \      \
 a     h      z  <-- level 2
  \
   d             <-- level 3

La gente le gusta número de cosas que empiezan con 0.)

Por lo tanto, si queremos visitar los elementos de nivel por nivel (y de izquierda a derecha, como de costumbre), comenzaríamos a nivel 0 con j, y luego ir al nivel 1 para F y K, y luego ir al nivel 2 para a, h y z, y, finalmente, ir a nivel 3 para d.

Este recorrido de nivel por nivel se llama un recorrido primero en amplitud, ya que exploramos la amplitud, es decir, la anchura completa del árbol en un nivel determinado, antes de ir más profundo.

Respondida el 14/04/2011 a las 08:16
fuente por usuario

votos
0

Me gustaría utilizar una colección, por ejemplo std::list, para almacenar todos los elementos del nivel actualmente impresa:

  1. Recoger punteros a todos los nodos en el nivel actual en el contenedor
  2. Imprimir los nodos que figuran en el envase
  3. Hacer un nuevo recipiente, añadir los subnodos de todos los nodos en el contenedor
  4. Sobrescribir el recipiente de edad con el nuevo contenedor
  5. repetir hasta que el recipiente está vacío
Respondida el 14/04/2011 a las 08:18
fuente por usuario

votos
0

como un ejemplo de lo que puede hacer en una entrevista si usted no recuerda / no conocen el algoritmo de "oficial", mi primera idea era - recorrer el árbol en la pre-orden regular arrastrando a lo largo de un contador de nivel, manteniendo una vector de listas enlazadas de punteros a nodos por nivel, por ejemplo

levels[level].push_back(&node);

y al final imprimir la lista de cada nivel.

Respondida el 14/04/2011 a las 08:39
fuente por usuario

votos
2

Si somos capaces de buscar el siguiente elemento en el mismo nivel, hemos terminado. Según nuestro conocimiento previo , podemos acceder a estos elementos usando primero en amplitud de recorrido.

Ahora único problema es cómo comprobar si estamos en el último elemento en cualquier nivel. Por esta razón, debemos estar añadiendo un delimitador (NULL en este caso) para marcar el final de un nivel.

Algoritmo: 1. Poner en cola de raíz.
2. NULL Poner en cola.
3. Mientras cola no está vacía
4. x = podido recuperar primer elemento de la cola
5. Si x no es NULL
6. x-> rpeer <= elemento superior de cola.
7. Use izquierda y hijo derecho de x en la cola
8. demás
9. Si la cola no está vacía
NULL 10. puesta en cola
11. final si
12. final mientras
13. retorno

#include <queue>

void print(tree* root)
{
  queue<tree*> que;
  if (!root)
      return;

  tree *tmp, *l, *r;
  que.push(root);
  que.push(NULL);

  while( !que.empty() )
  {
      tmp = que.front();
      que.pop();
      if(tmp != NULL)
      {
          cout << tmp=>val;  //print value
          l = tmp->left;
          r = tmp->right;
          if(l) que.push(l);
          if(r) que.push(r);
      }
      else
      {
          if (!que.empty())
              que.push(NULL);
      }
  }
  return;
}
Respondida el 14/04/2011 a las 11:55
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more