binaire boom -print de elementen volgens het niveau

stemmen
6

Deze vraag werd gevraagd om me in een interview:

binaire

laten we zeggen dat we boven binaire boom, hoe kan ik een uitgangssignaal zoals hieronder

2 7 5 2 6 9 5 11 4

i beantwoordt dergelijke kan zijn kunnen we gelijke variabele count hebben en alle elementen achtereenvolgens afdrukken door het controleren van het niveau variabele count van elk knooppunt. Waarschijnlijk was ik verkeerd.

kan iemand anyidea over hoe we dat kunnen bereiken?

De vraag is gesteld op 14/04/2011 om 08:07
bron van user
In andere talen...                            


7 antwoorden

stemmen
2

De traversal in uw vraag wordt genoemd level-order traversalen dit is hoe het moet (zeer eenvoudig / schoon stukje code ik vond).

U gebruikt in feite een wachtrij en de volgorde van bewerkingen ziet er ongeveer als volgt uit:

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

Voor deze boom (rechtstreeks van Wikipedia):
voer image beschrijving hier

antwoordde op 14/04/2011 om 08:14
bron van user

stemmen
2

De term daarvoor is level-order traversal . Wikipedia beschrijft een algoritme voor dat het gebruik van een wachtrij :

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)
antwoordde op 14/04/2011 om 08:14
bron van user

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

Iteratieve verdieping zou ook werken en bespaart geheugen gebruik, maar ten koste van de rekentijd.

antwoordde op 14/04/2011 om 08:16
bron van user

stemmen
6

Je moet een breedte eerste traversal van de boom te doen. Hier wordt het als volgt omschreven:

Breedte-first traversal: Diepte-eerst is niet de enige manier om te gaan door de elementen van een boom. Een andere manier is om te gaan door hen level-by-niveau.

Bijvoorbeeld, elk element bestaat op een bepaald niveau (of diepte) van de boom:

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

mensen willen het aantal dingen te beginnen met 0.)

Dus, als we willen dat de elementen bezoeken level-by-niveau (en van links naar rechts, zoals gewoonlijk), zouden we beginnen op niveau 0 met j, ga dan naar niveau 1 voor f en k, ga dan naar niveau 2 voor a, h en z en eindelijk naar niveau 3 voor d.

Dit niveau-by-level traversal wordt een breedte-first traversal, omdat we de breedte, dat wil zeggen, de volledige breedte van de boom te verkennen op een bepaald niveau, alvorens dieper.

antwoordde op 14/04/2011 om 08:16
bron van user

stemmen
0

Ik zou een verzameling, bijvoorbeeld gebruiken std::list, om alle elementen van de momenteel gedrukte niveau op te slaan:

  1. Verzamel verwijzingen naar alle knooppunten in het huidige niveau in de houder
  2. Druk het in de container opgenomen knooppunten
  3. Maak een nieuwe container, voeg de subnodes van alle knooppunten in de container
  4. Overschrijven de oude container met de nieuwe container
  5. herhalen totdat container leeg
antwoordde op 14/04/2011 om 08:18
bron van user

stemmen
0

als een voorbeeld van wat u kunt doen in een interview als je niet meer weet / niet de "officiële" algoritme weet het, mijn eerste idee was - traverse de boom in de reguliere pre-order een niveau teller mee te slepen, het handhaven van een vector van gekoppelde-lijsten met verwijzingen naar knooppunten per niveau, bijvoorbeeld

levels[level].push_back(&node);

en uiteindelijk de lijst afdrukken van elk niveau.

antwoordde op 14/04/2011 om 08:39
bron van user

stemmen
2

Als we in staat zijn om het volgende element op hetzelfde niveau te halen, zijn we klaar. Per onze voorkennis , kunnen we toegang tot deze element met behulp van de breedte eerste traversal.

Nu enige probleem is hoe om te controleren of we nu eindelijk element op elk niveau. Daarom moeten we voegen scheidingsteken (NULL in dit geval) naar het einde van een merkteken.

Algoritme: 1. Zet wortel in wachtrij.
2. Zet NULL in de wachtrij.
3. Hoewel wachtrij niet leeg
4.x = ophalen eerste element uit de wachtrij
5. Indien x niet NULL
6. x-> rpeer <= topelement wachtrij.
7. Trek linker en rechter kind van x in rij
8. anders
9. Als wachtrij niet leeg
10. put NULL in rij
11. end if
12. end tijdens
13. rendement

#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;
}
antwoordde op 14/04/2011 om 11:55
bron van user

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