Beregne høyden på et tre

stemmer
3

Jeg prøver å beregne høyden på et tre. Jeg doint med koden skrevet under.

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

}

Det gir meg corret resultat. Men i noen innlegg (googlet side) Det ble foreslått å gjøre en Postorder traversering og bruke denne høyden metode for å beregne høyde. Noen spesiell grunn?

Publisert på 17/02/2010 klokken 08:07
kilden bruker
På andre språk...                            


5 svar

stemmer
2

Høyden på treet endrer ikke med traversering. Det forblir konstant. Det er sekvensen av nodene som endres avhengig av traverseringen.

Svarte 17/02/2010 kl. 08:17
kilden bruker

stemmer
14

Men er ikke en Postorder traversering nøyaktig hva du gjør? Forutsatt venstre og høyre er både ikke-null, må du først gjøre height(left), da height(right), og litt til bearbeiding i den aktuelle noden. Det er Postorder traversering i henhold til meg.

Men jeg ville skrive det slik:

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

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

Edit: avhengig av hvordan du definerer trehøyden, bør base case (for en tom treet) være 0 eller -1.

Svarte 17/02/2010 kl. 08:19
kilden bruker

stemmer
2

Definisjoner fra wikipedia .

Preorder (dybde-først):

  1. Besøk roten.
  2. Traversere venstre treet.
  3. Traverse høyre subtre.

Inorder (symmetrisk):

  1. Traversere venstre treet.
  2. Besøk roten.
  3. Traverse høyre subtre.

Postorder:

  1. Traversere venstre treet.
  2. Traverse høyre subtre.
  3. Besøk roten.

"Besøk" i definisjonene betyr "beregne høyden på node". Som i ditt tilfelle er enten null (både venstre og høyre er null) eller 1 + kombinert høyde for barn.

I implementeringen, den traversering rekkefølgen spiller ingen rolle, det ville gi de samme resultatene. Cant egentlig si noe mer enn at uten en link til kilden sier Postorder er å foretrekke.

Svarte 17/02/2010 kl. 08:27
kilden bruker

stemmer
4

Koden vil mislykkes i trær hvor minst en av nodene har bare ett barn:

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

Hvis treet har to noder (roten og enten venstre eller høyre barn) kaller metoden på rot vil ikke oppfylle den første betingelsen (minst en av undertrærne er ikke-tom), og det vil ringe rekursivt på begge barn. En av dem er null, men fortsatt vil det dereference nullpeker til å utføre if.

En riktig løsning er en postet av Hans her. I alle fall må du velge hvilken metode invarianter er: enten du tillater samtaler hvor argumentet er null, og du håndtere det elegant eller annet du trenger argumentet for å være ikke-null og garantere at du ikke kaller metoden med nullpekere .

Det første tilfellet er tryggere hvis du ikke kontrollerer alle inngangspunkter (metoden er publikum som i koden) siden du ikke kan garantere at eksterne koden ikke vil passere nullpekere. Den andre løsningen (endre signaturen til referanse, og gjør det til en medlem metoden i treeklassen) kan være renere (eller ikke) hvis du kan styre alle inngangspunkter.

Svarte 17/02/2010 kl. 08:40
kilden bruker

stemmer
0

Her er svaret:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
Svarte 18/02/2015 kl. 20:02
kilden bruker

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