albero binario -PRINT gli elementi secondo livello

voti
6

Questa domanda è stato chiesto di me in un'intervista:

albero

Consente di dire che abbiamo sopra albero binario, come posso produrre un output come qui di seguito

2 7 5 2 6 9 5 11 4

ho risposto simili possono essere possiamo avere una variabile conteggio livello e stampare tutti gli elementi sequenzialmente controllando la variabile conteggio livello di ciascun nodo. probabilmente mi sbagliavo.

chiunque può dare anyidea su come possiamo ottenere che?

È pubblicato 14/04/2011 alle 06:07
fonte dall'utente
In altre lingue...                            


7 risposte

voti
2

L'attraversamento in questione si chiama un level-order traversale questo è come si fa (snippet molto semplice / pulito il codice che ho trovato).

Che, fondamentalmente, utilizza una coda e l'ordine delle operazioni sarà simile a questa:

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

Per questo albero (direttamente da Wikipedia):
entrare descrizione dell'immagine qui

Risposto il 14/04/2011 a 06:14
fonte dall'utente

voti
2

Il termine di ciò è il livello-ordine di attraversamento . Wikipedia descrive un algoritmo per che l'utilizzo di una coda :

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)
Risposto il 14/04/2011 a 06:14
fonte dall'utente

voti
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);
}

approfondimento iterativo potrebbe anche funzionare e consente di risparmiare l'utilizzo della memoria, ma a scapito del tempo di calcolo.

Risposto il 14/04/2011 a 06:16
fonte dall'utente

voti
6

Hai bisogno di fare una larghezza prima attraversamento dell'albero. Qui è descritto come segue:

Breadth-first traversal: profondità prima non è l'unico modo per passare attraverso gli elementi di un albero. Un altro modo è quello di passare attraverso di loro livello-da-livello.

Ad esempio, ciascun elemento esiste a un certo livello (o profondità) nell'albero:

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

Alla gente piace cose numero che inizia con 0.)

Quindi, se vogliamo visitare agli elementi di livello-da-livello (e da sinistra a destra, come al solito), avremmo iniziato a livello 0 con j, quindi passare al livello 1 per f e k, poi passare al livello 2 per una, he z, e infine passare al livello 3 per d.

Questo attraversamento level-by-livello è chiamato un attraversamento in ampiezza, perché esploriamo l'ampiezza, vale a dire, larghezza della pianta ad un dato livello, prima di andare più in profondità.

Risposto il 14/04/2011 a 06:16
fonte dall'utente

voti
0

Vorrei usare una collezione, per esempio std::list, per memorizzare tutti gli elementi del livello attualmente stampata:

  1. Raccogliere puntatori a tutti i nodi nel livello corrente nel contenitore
  2. Stampa i nodi elencati nel contenitore
  3. Fare un nuovo contenitore, aggiungere le sotto-nodi di tutti i nodi nel contenitore
  4. Sovrascrivere il vecchio contenitore con il nuovo contenitore
  5. ripetere fino contenitore è vuoto
Risposto il 14/04/2011 a 06:18
fonte dall'utente

voti
0

come un esempio di cosa si può fare durante un colloquio, se non ti ricordi / non conoscono l'algoritmo "ufficiale", la mia prima idea era - attraversare l'albero nel regolare pre-ordine trascinando un segnalino livello lungo, il mantenimento di un vettore collegate liste di puntatori ai nodi per ogni livello, ad esempio,

levels[level].push_back(&node);

e alla fine stampare l'elenco di ogni livello.

Risposto il 14/04/2011 a 06:39
fonte dall'utente

voti
2

Se siamo in grado di recuperare l'elemento successivo allo stesso livello, abbiamo finito. Come per la nostra conoscenza prima , siamo in grado di accedere a questi elementi utilizzando ampiezza primo attraversamento.

Ora unico problema è come controllare se siamo finalmente elemento a qualsiasi livello. Per questo motivo, dovremmo aggiungendo un delimitatore (NULL in questo caso) per marcare fine di un livello.

Algoritmo: 1. Mettere radici nella coda.
2. NULL Mettere in coda.
3. Mentre coda non è vuota
4. x = recuperare primo elemento dalla coda
5. Se x non è NULL
6. x-> rpeer <= elemento superiore della coda.
7. put sinistro e figlio destro di x nella coda
8. altro
9. se coda non è vuota
10. put NULL nella coda
11. fine se
12. fine, mentre
13. ritorno

#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;
}
Risposto il 14/04/2011 a 09:55
fonte dall'utente

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