Calculați înălțimea unui copac

voturi
3

Am încercat să calculeze înălțimea unui copac. Sunt doint cu codul scris de mai jos.

#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);*/

}

Îmi dă rezultate corret. Dar , în unele posturi (pagina googled) Sa sugerat sa faci un traversal postordine și de a folosi această metodă înălțime pentru calcularea înălțimii. Orice motiv anume?

Întrebat 17/02/2010 la 09:07
sursa de către utilizator
În alte limbi...                            


5 răspunsuri

voturi
2

Înălțimea arborelui nu se schimba cu traversal. Ea rămâne constantă. Este secvența de noduri care se schimbă în funcție de traversal.

Publicat 17/02/2010 la 09:17
sursa de către utilizator

voturi
14

Dar nu este un traversal postordine exact ceea ce faci? Presupunând că stânga și dreapta sunt ambele nenulă, să faceți mai întâi height(left), apoi height(right), și apoi unele de prelucrare în nodul curent. Asta e Traversarea postordine în conformitate cu mine.

Dar mi-ar scrie așa:

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

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

Editare: în funcție de modul în care definiți înălțimea arborelui, cazul de bază (pentru un arbore gol) ar trebui să fie 0 sau -1.

Publicat 17/02/2010 la 09:19
sursa de către utilizator

voturi
2

Definiții din wikipedia .

Precomanda (adancime):

  1. Accesați rădăcină.
  2. Traverse subarborele din stânga.
  3. Traversa subarborelui drept.

Inorder (simetrice):

  1. Traverse subarborele din stânga.
  2. Accesați rădăcină.
  3. Traversa subarborelui drept.

postordine:

  1. Traverse subarborele din stânga.
  2. Traversa subarborelui drept.
  3. Accesați rădăcină.

„Vizita“ în definițiile înseamnă „calcula înălțimea de nod“. Care, în cazul dumneavoastră este fie zero (atât la stânga și dreapta sunt nule) sau 1 + înălțimea combinată a copiilor.

În implementarea, ordinea nu contează traversal, ar da aceleași rezultate. Supraînălțare într-adevăr vă spun ceva mai mult decât atât, fără un link către sursa care să ateste postordine este de a prefera.

Publicat 17/02/2010 la 09:27
sursa de către utilizator

voturi
4

Codul va eșua în copaci în cazul în care cel puțin unul dintre nodurile are un singur copil:

// 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);
//...

Dacă arborele are două noduri (rădăcină și fie un copil la stânga sau la dreapta) apelarea metodei de pe rădăcină nu va îndeplini prima condiție (cel puțin una dintre subramificații este non-gol) si va apela recursiv pe ambii copii. Una dintre ele este nul, dar totuși va endiancu indicatorul nul pentru a efectua if.

O soluție corectă este cel postat de Hans aici. În orice caz , trebuie să alegeți ce invarianți tale metode sunt: fie vă permit efectuarea apelurilor în cazul în care argumentul este nul și te descurci cu grație sau altceva aveți nevoie argumentul să fie nenulă și garanția că nu apelați metoda cu indicii nule .

Primul caz este mai sigur dacă nu controlează toate punctele de intrare (metoda este publică ca și în codul dvs.) deoarece nu se poate garanta că codul extern nu va trece indicii nule. A doua soluție (schimbarea semnăturii pentru referință, și făcându - l o metodă membru al treeclasei) ar putea fi mai curat (sau nu) în cazul în care puteți controla toate punctele de intrare.

Publicat 17/02/2010 la 09:40
sursa de către utilizator

voturi
0

Iată răspunsul:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
Publicat 18/02/2015 la 20:02
sursa de către utilizator

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