Oblicz wysokość drzewa

głosy
3

Próbuję obliczyć wysokość drzewa. Ja doint z kodu napisanego poniżej.

#include<iostream.h>

struct tree
{
    int data;
    struct tree * left;
    struct tree * right;
};

typedef struct tree tree;

class Tree
{
private:
    int n;
    int data;
    int l,r;
public:
    tree * Root;
    Tree(int x)
    {
        n=x;
        l=0;
        r=0;
        Root=NULL;
    }
    void create();
    int height(tree * Height);

};

void Tree::create()
{
    //Creting the tree structure
} 

int Tree::height(tree * Height)
{
    if(Height->left==NULL && Height->right==NULL)
    {return 0;
    }
    else
    {
        l=height(Height->left);
        r=height(Height->right);

        if (l>r)
        {l=l+1;
        return l;
        }
        else
        {
            r=r+1;
            return r;
        }
    }
}

int main()
{
    Tree A(10);//Initializing 10 node Tree object
    A.create();//Creating a 10 node tree

    cout<<The height of tree<<A.height(A.Root);*/

}

To daje mi wynik Corret. Ale w niektórych stanowisk (google strona) Zasugerowano uwagi na przechodzenie Postorder i używać tej metody wysokość obliczyć wysokość. Wszelkie konkretny powód?

Utwórz 17/02/2010 o 09:07
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
2

Wysokość drzewa nie zmienia się z przechodzenia. Pozostaje stała. Jest to sekwencja węzłów, które zmieniają się w zależności od przechodzenia.

Odpowiedział 17/02/2010 o 09:17
źródło użytkownik

głosy
14

Ale nie jest przechodzenie postorder dokładnie to, co robisz? Zakładając, że lewy i prawy są zarówno niezerowe, trzeba najpierw zrobić height(left), a potem height(right), a potem niektóre przetwarzania w bieżącym węźle. To postorder przejścia według mnie.

Ale chciałbym napisać to tak:

int Tree::height(tree *node) {
    if (!node) return -1;

    return 1 + max(height(node->left), height(node->right));
}

Edit: w zależności od sposobu zdefiniowania wysokość drzewa, sprawa podstawowa (dla pustego drzewa) powinna wynosić 0 lub -1.

Odpowiedział 17/02/2010 o 09:19
źródło użytkownik

głosy
2

Definicje z wikipedii .

Preorder (głębokość pierwszego)

  1. Odwiedź korzeń.
  2. Trawers w lewo poddrzewa.
  3. Trawers prawego poddrzewa.

Inorder (symetryczne)

  1. Trawers w lewo poddrzewa.
  2. Odwiedź korzeń.
  3. Trawers prawego poddrzewa.

Po zamówieniu:

  1. Trawers w lewo poddrzewa.
  2. Trawers prawego poddrzewa.
  3. Odwiedź korzeń.

„Wizyta” w definicji oznacza „obliczyć wysokość węzła”. Która w danym przypadku jest albo zero (zarówno z lewej i prawej są null) lub 1 + połączeniu wysokość dzieci.

W implementacji, kolejność przejścia nie ma znaczenia, to daje takie same wyniki. Nie mogę naprawdę powiedzieć coś więcej niż, że bez linku do źródła stwierdzające postorder jest wolą.

Odpowiedział 17/02/2010 o 09:27
źródło użytkownik

głosy
4

Kod nie powiedzie się na drzewach, gdzie co najmniej jeden z węzłów ma tylko jedno dziecko:

// code snippet (space condensed for brevity)
int Tree::height(tree * Height) {
    if(Height->left==NULL && Height->right==NULL) { return 0; }
    else {
        l=height(Height->left);
        r=height(Height->right);
//...

Jeśli drzewo ma dwa węzły (korzeń i albo w lewo lub w prawo dziecka) wywołanie metody na korzeń nie będzie spełniać warunek pierwszy (przynajmniej jeden z poddrzew jest niepusty) i będzie zadzwonić rekursywnie zarówno dzieci. Jednym z nich jest zerowa, ale nadal będzie to dereference null pointer aby wykonać if.

Prawidłowe rozwiązanie jest jedno wysłane przez Hans tutaj. W każdym razie trzeba wybrać to, co metoda, niezmienniki są: albo pozwolić połączenia gdzie argument jest null i obsługiwać że wdziękiem albo wymagają argumentu być niezerowe i gwarancji, że nie wywołać metodę z wartością null wskaźniki ,

Pierwszy przypadek jest bezpieczniejszy, jeśli nie kontrolują wszystkie punkty wejścia (metoda jest publiczna, jak w kodzie), ponieważ nie można zagwarantować, że kod zewnętrzny nie przejdzie zerowe wskaźniki. Drugie rozwiązanie (zmianę sygnatury odniesienia, a co sprawia, że metody członkiem treeklasy) mogłyby być czystsze (lub nie), czy można kontrolować wszystkie punkty wejścia.

Odpowiedział 17/02/2010 o 09:40
źródło użytkownik

głosy
0

Oto odpowiedź:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
Odpowiedział 18/02/2015 o 20:02
źródło użytkownik

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