Drzewa binarne - Tracing poprzez kod

głosy
0

Biorąc pod uwagę binarne drzewo poniżej, określić kolejność, w której węzły drzewa binarnego Poniżej znajdują odwiedził zakładając funkcję A (root) jest wywoływany. Załóżmy, że węzły drzewa i wskaźniki są zdefiniowane jak pokazano. Zakładamy, że korzeń jest wskaźnik do węzła zawierającego 60. Moja odpowiedź na ten problem jest podana poniżej. Czy to jest poprawne? Co zrobiłem źle?

                                   60
                                 /    \
                                30     90
                               /  \   / 
                              5   38  77
                               \  /  / \
                               8 32 62  88



struct treeNode{
  int data;
  struct treeNode *left, *right:
  {

struct treeNode *tree_ptr;

void A(struct treeNode *node_ptr){
    if (node_ptr != NULL){
    printf(“%d ,”,node_ptr->data);
    B(node_ptr->left);
    B(node_ptr->right);
   }   
}

void B(struct treeNode *node_ptr){
    if (node_ptr != NULL) {
    A(node_ptr->left);
    printf(“%d ,”,node_ptr->data);
    A(node_ptr->right);
   }
 }   

Odpowiedź: W void A on mówi do pierwszego wydruku node_ptr-> Dane więc 60 zostanie wydrukowanych wówczas funkcja zwraca B (node_ptr-> w lewo), a następnie w ciągu B, A jest wywoływana (node_ptr-> po lewej), a następnie wydrukować, że dane, które jest 5 ., a następnie (node_ptr-> prawo) jest wywoływana wrócić aż do druku, że dane tak 8 zostanie wydrukowany. Teraz nie jestem taki pewien, co robić dalej, ale pojawia się logicznie byłoby sensu drukować 30, ale nie jestem pewien, jak ptr dostaje od 8 do 30. A potem, jeśli nadal w tym samym deseniu 38 i 32 zostanie wydrukowany zostanie wydrukowany. Na prawym poddrzewie ... 90 77 62 88

Utwórz 14/12/2010 o 22:05
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
1

Na początek, kod ma kilka błędów w nim. Zgaduję, powinno być więcej tak:

struct treeNode{
  int data;
  struct treeNode *left, *right;
}

treeNode *tree_ptr;

void A(treeNode *node_ptr){
    if (node_ptr != NULL){  /// this could be just if(node_ptr)
        printf(“%d ,”,node_ptr->data);
        B(node_ptr->left);
        B(node_ptr->right);
    }   
}

void B(treeNode *node_ptr){
    if (node_ptr != NULL) {
        A(node_ptr->left);
        printf(“%d ,”,node_ptr->data);
        A(node_ptr->right);
    }
}   

Ty także mieszanie dwóch różnych algorytmów przemierzania. A()jest pre-order, B()będzie już w porządku. A()i B()powinny być nazywając siebie, a nie siebie. (Jeszcze jeden powód, aby użyć zmiennej rzeczywistej / nazwy funkcji zamiast A, Bi takie.)

Odpowiedział 14/12/2010 o 22:11
źródło użytkownik

głosy
1

Wystarczy napisać pełny stos realizacji w czasie. Lubię to:

A(60)
  printf
  B(30)
    A(5)
      ...
    printf
    A(38)
      ...
  B(90)
    ...

(Reszta z drzewa pozostawiony jako wykonywania do czytnika).

Następnie wystarczy przejść od góry do dołu, zapisując wyniki sprawozdania printf.

Odpowiedział 14/12/2010 o 22:14
źródło użytkownik

głosy
1

Ajest wstępnie przejścia rzędu, podczas gdy Bjest przechodzenie w prawidłowej kolejności.

Łatwym sposobem, aby dowiedzieć się kolejność drukowania jest przyjrzenie się, jak odwiedzić same węzły. Ja zwykle narysować kontur wokół zewnętrznej części drzewa (zaczynając od korzenia i poruszając się w lewo lub w prawo w zależności od sub-tree jesteś przechodzącego pierwszy). Jeśli robie przechodzenie pre-order, mogę wydrukować węzeł ilekroć przemieszczania wzdłuż jej na zewnątrz . Jeśli robie to przechodzenie na zamówienie, mogę wydrukować węzeł tylko kiedy przenieść pod nim (ma to sens, jeśli spojrzeć na zamówienie przechodzenia przez, ponieważ kończy się wydrukowaniem liście pierwszy, są pierwsze węzły przenoszone pod kiedy narysować kontur). Jeśli robie przechodzenie po zamówienie, wydrukować węzeł tylko wtedy, gdy poruszają się po jego wewnętrznej stronie .

AKTUALIZACJA

Powodem 30 zostanie wydrukowana po 5 i 8 jest to, że nie wykonujesz przechodzenie czysto pre-order. Jesteś skoki między pre-order i przechodzenie na zamówienie.

Łatwym sposobem, aby dowiedzieć się kolejność jest rzeczywiście zapisz kroki kod przechodzi jak śledzić przez niego (ja często używać Pen / ołówek i papier, aby informacje razem). Na przykład, można zrobić wypisać call-stack takiego:

A(60)
  printf(60)
  call B(60.left)
    B(30)
      call A(30.left)
        A(5)
          printf(5)
          call B(5.left)
            B(null)
          call B(5.right)
            B(8)
              call A(8.left)
                A(null)
              printf(8)
              call A(8.right)
                A(null)
      printf(30)
      call A(30.right)
        A(38)
        ...

Można łatwo sprawdzić kolejność, w której węzły są drukowane, a co ważniejsze, dlaczego ty „skakać” z drukowania 8 do drukowania 30 (jedno wywołanie rekurencyjne zakończyła i spadasz o jeden poziom).

Odpowiedział 14/12/2010 o 22:15
źródło użytkownik

głosy
1

śledzenia, jak wskazano powyżej, nie może być prawdziwe zarówno dla pre-kolejności lub zamówienie pre - 60, 30, 5, 8 35 32, itp W - 5, 8, 30, 32, 35 itd.

Odpowiedział 28/03/2011 o 09:59
źródło użytkownik

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