binært tre -trykk elementene i henhold til nivået

stemmer
6

Dette spørsmålet ble stilt til meg i et intervju:

binærtreet

kan si vi har ovenfor binært tre, hvordan kan jeg lage en produksjon som nedenfor

2 7 5 2 6 9 5 11 4

Jeg svarte som kanskje vi kan ha et nivå teller variabel og skrive ut alle elementene i rekkefølge ved å kontrollere nivået teller variabel for hver node. sannsynligvis jeg var galt.

kan noen gi anyidea om hvordan vi kan oppnå det?

Publisert på 14/04/2011 klokken 07:07
kilden bruker
På andre språk...                            


7 svar

stemmer
2

Den traversering i spørsmålet ditt er kalt en level-order traversalog dette er hvordan det skal gjøres (veldig enkel / ren kodebit jeg fant).

Du i utgangspunktet bruke en kø, og rekkefølgen av operasjoner vil se omtrent slik ut:

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

For dette treet (rett fra Wikipedia):
skriv bildebeskrivelse her

Svarte 14/04/2011 kl. 07:14
kilden bruker

stemmer
2

Begrepet for dette er nivået på bestilling traversering . Wikipedia beskriver en algoritme for at bruk av en kø :

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)
Svarte 14/04/2011 kl. 07:14
kilden bruker

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

Iterativ dypere vil også arbeide og sparer minnebruk, men på bekostning av regnetid.

Svarte 14/04/2011 kl. 07:16
kilden bruker

stemmer
6

Du må gjøre en bredde først traversering av treet. Her er det beskrevet som følger:

Bredde-først traversering: Dybde-først er ikke den eneste måten å gå gjennom elementene i et tre. En annen måte er å gå gjennom dem level-by-nivå.

For eksempel, eksisterer hvert element i en viss høyde (eller dybde) i treet!

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

Folk liker å tall ting som starter med 0.)

Så, hvis vi ønsker å besøke elementene nivå-by-nivå (og fra venstre til høyre, som vanlig), ville vi starter på nivå 0 med j, så gå til nivå 1 for f og k, så gå til nivå 2 for a, t og z, og til slutt går til nivå 3 for d.

Dette nivået-by-nivå traversering kalles et bredde-først traversering fordi vi utforske bredden, dvs. hele bredden av treet på et gitt nivå, før du går dypere.

Svarte 14/04/2011 kl. 07:16
kilden bruker

stemmer
0

Jeg ville bruke en samling, for eksempel std::list, å lagre alle elementene i dag trykt nivå:

  1. Samle pekere til alle nodene i det aktuelle nivået i beholderen
  2. Print nodene som er oppført i beholderen
  3. Lag en ny container, tilsett subnodes av alle noder i beholderen
  4. Overskrive den gamle beholderen med den nye beholderen
  5. gjentas inntil beholderen er tom
Svarte 14/04/2011 kl. 07:18
kilden bruker

stemmer
0

som et eksempel på hva du kan gjøre på et intervju hvis du ikke husker / vet ikke "offisielle" algoritme, min første idé var - travers treet i den ordinære pre-order dra en nivåteller sammen, opprettholde en vektor av koblede lister~~POS=HEADCOMP av pekere for å noder pr nivå, f.eks

levels[level].push_back(&node);

og til slutt skrive ut listen av hvert nivå.

Svarte 14/04/2011 kl. 07:39
kilden bruker

stemmer
2

Hvis vi er i stand til å hente det neste elementet på samme nivå, er vi ferdig. Pr vår tidligere kunnskap , kan vi få tilgang til disse element ved hjelp av bredde først traversering.

Nå eneste problemet er hvordan man skal sjekke om vi er på siste elementet på ethvert nivå. Av denne grunn bør vi tilføye et skilletegn (NULL i dette tilfellet) for å markere slutten av et nivå.

Algoritme: 1. Sett rot i køen.
2. Sett NULL i køen.
3. Mens køen ikke er tom
4. x = hente første element fra køen
5. Hvis x er ikke er NULL
6. x-> rpeer <= toppelementet av køen.
7. Sett venstre og høyre barn av x i kø
8. ellers
9. hvis køen ikke er tom
10. Sett NULL i kø
11. slutt dersom
12. enden, mens
13 retur

#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;
}
Svarte 14/04/2011 kl. 10:55
kilden bruker

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