Binärbaum -print die Elemente entsprechend dem Niveau

stimmen
6

Diese Frage wurde mir in einem Interview gefragt:

Binärbaum

können sagen, dass wir über binären Baum haben, wie kann ich eine Ausgabe wie unten erzeugen

2 7 5 2 6 9 5 11 4

Ich antwortete, wie sein können wir eine Ebene Zählvariable haben und ausdrucken können alle Elemente nacheinander durch den Pegel Zählvariable von jedem Knoten zu überprüfen. wahrscheinlich ich war falsch.

kann jemand anyidea so geben, wie wir das erreichen können?

Veröffentlicht am 14/04/2011 um 08:07
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
2

Die Traversal in Ihrer Frage ist eine genannt level-order traversalund dies ist , wie es (sehr einfach / sauber Code - Schnipsel gefunden) getan hat.

Sie verwenden im Grunde eine Warteschlange und die Reihenfolge der Operationen werden wie folgt aussehen:

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

Für diesen Baum (gerade aus Wikipedia):
Geben Sie hier image description

Beantwortet am 14/04/2011 um 08:14
quelle vom benutzer

stimmen
2

Der Begriff dafür ist Level-Order Traversal . Wikipedia beschreibt einen Algorithmus für die eine Warteschlange mit :

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)
Beantwortet am 14/04/2011 um 08:14
quelle vom benutzer

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

Iterative Vertiefung würde auch und speichert die Speichernutzung, aber auf Kosten der Rechenzeit.

Beantwortet am 14/04/2011 um 08:16
quelle vom benutzer

stimmen
6

Sie benötigen einen Breitendurchlauf des Baumes zu tun. Hier wird beschrieben , wie folgt:

Breiten erste Traversal: Depth-first ist nicht die einzige Art und Weise durch die Elemente eines Baumes zu gehen. Ein anderer Weg ist durch sie Level-by-Ebene zu gehen.

Beispielsweise besteht jedes Element auf einer bestimmten Höhe (oder Tiefe) in der Struktur:

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

Menschen wie zu Nummer Dinge, beginnend mit 0)

Also, wenn wir die Elemente Level-by-Ebene (und von links nach rechts, wie üblich) besuchen wollen, müssen wir auf der Ebene 0 mit j beginnen würden, dann gehen Sie auf Stufe 1 für f und k, geht dann auf Stufe 2 für a, h und z, und schließlich auf Stufe 3 für d gehen.

Dieser Level-by-Level-Traversal ist eine Breiten ersten Traversal genannt, weil wir die Breite, dh volle Breite des Baumes auf einem bestimmten Niveau erkunden, bevor tiefer gehen.

Beantwortet am 14/04/2011 um 08:16
quelle vom benutzer

stimmen
0

Ich würde eine Sammlung verwenden, zum Beispiel std::list, um alle Elemente der aktuell gedruckten Ebene zu speichern:

  1. Sammeln Sie Zeiger auf alle Knoten im aktuellen Füllstand im Behälter
  2. Drucken Sie die Knoten in dem Behälter enthalten sind
  3. Machen Sie einen neuen Container, fügen Sie die untergeordneten Knoten aller Knoten in dem Behälter
  4. Überschreiben Sie den alten Behälter mit dem neuen Behälter
  5. wiederholen, bis der Behälter leer ist
Beantwortet am 14/04/2011 um 08:18
quelle vom benutzer

stimmen
0

als ein Beispiel das, was Sie in einem Interview tun können, wenn Sie / weißt nicht mehr, nicht den „offiziellen“ Algorithmus nicht wissen, meine erste Idee war - Verfahrweg des Baumes in der regulären vorbestellen entlang eine Ebene Zähler ziehen, eine Aufrechterhaltung Vektor verknüpfter Listen von Zeigern pro Ebene zu den Knoten, zB

levels[level].push_back(&node);

und am Ende drucken Sie die Liste eines jeden Levels.

Beantwortet am 14/04/2011 um 08:39
quelle vom benutzer

stimmen
2

Wenn wir das nächste Element auf dem gleichen Niveau zu holen sind in der Lage, sind wir fertig. Gemäß unserem Vorwissen können wir diese Elemente unter Verwendung von Breiten Traversal zuzugreifen.

Jetzt nur Problem ist, wie zu überprüfen, ob wir endlich Element auf jeder Ebene sind. Aus diesem Grunde sollen wir ein Trennzeichen (NULL in diesem Fall) zu markieren Ende eines Levels werden anhängen.

Algorithmus: 1. Setzen Wurzel in der Warteschlange.
2. Setzen Sie NULL in der Warteschlange.
3. Während Warteschlange nicht leer ist ,
4. x = fetch erste Element aus der Warteschlange
5. Wenn x nicht NULL ist
6. x-> rpeer <= top Element der Warteschlange.
7. Setzen Sie nach links und rechts Kind von x in der Warteschlange
8. sonst
9. wenn Warteschlange nicht leer ist
10. Put NULL in der Warteschlange
11 end if
12 Ende , während
13 Rückkehr

#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;
}
Beantwortet am 14/04/2011 um 11:55
quelle vom benutzer

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