Bereken hoogte van een boom

stemmen
3

Ik probeer om de hoogte van een boom te berekenen. Ik doint met de onderstaande code geschreven.

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

}

Het geeft me corret resultaat. Maar in sommige posten (googled pagina) Er werd voorgesteld om te doen een Postorder traversal en het gebruik van deze hoogte methode om de hoogte te berekenen. Eventuele specifieke reden?

De vraag is gesteld op 17/02/2010 om 09:07
bron van user
In andere talen...                            


5 antwoorden

stemmen
2

De hoogte van de boom niet veranderen met de traversal. Blijft constant. Het is de volgorde van de knooppunten die veranderen afhankelijk van de traversal.

antwoordde op 17/02/2010 om 09:17
bron van user

stemmen
14

Maar is het niet een postorder traversal precies wat je doet? Ervan uitgaande links en rechts zijn beide niet-nul, moet je eerst doen height(left), dan height(right), en vervolgens een aantal verwerking in het huidige knooppunt. Dat is postorder traversal volgens mij.

Maar ik zou schrijven als volgt uit:

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

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

Edit: afhankelijk van hoe u boomhoogte definiëren, de base case (voor een lege boom) moet 0 zijn of -1.

antwoordde op 17/02/2010 om 09:19
bron van user

stemmen
2

Definities van wikipedia .

Preorder (diepte-eerst):

  1. Bezoek de wortel.
  2. Doorkruisen de linker deelboom.
  3. Traverse de rechter deelboom.

Inorder (symmetrische):

  1. Doorkruisen de linker deelboom.
  2. Bezoek de wortel.
  3. Traverse de rechter deelboom.

Postbestelling:

  1. Doorkruisen de linker deelboom.
  2. Traverse de rechter deelboom.
  3. Bezoek de wortel.

"Bezoek" in de definities betekent "bereken hoogte van knooppunt". Die in het geval ofwel nul (zowel links en rechts null) of 1 + gecombineerde lengte van kinderen.

In uw implementatie, de traversal volgorde maakt niet uit, het zou geven dezelfde resultaten. Kan je echt zeggen iets meer dan dat zonder een link naar uw bron vermelding van postorder is te verkiezen.

antwoordde op 17/02/2010 om 09:27
bron van user

stemmen
4

De code zal falen in de bomen, waar ten minste één van de knooppunten heeft slechts één kind:

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

Als de boom heeft twee knooppunten (de wortel en ofwel een linker of rechter kind) aanroepen van de methode van de wortel zal niet voldoen aan de eerste voorwaarde (ten minste één van de substructuren is niet leeg) en het zal recursief een beroep doen op zowel kinderen. Een van hen is nul, maar toch zal het dereference de null pointer naar de uit te voeren if.

Een juiste oplossing is degene gepost door Hans hier. In ieder geval moet je kiezen wat uw methode invarianten worden: of je oproepen waarbij het argument null is toe te staan en je omgaat die zich netjes of anders je het argument vereisen niet-nul en garantie dat je niet bellen met de methode met null pointers te zijn .

In het eerste geval is veiliger als je geen controle over alle toegangspunten (de methode is openbaar als in uw code), omdat je niet kan garanderen dat de externe code niet null pointers zal passeren. De tweede oplossing (het veranderen van de handtekening te verwijzen, en waardoor het een lid methode van de treeklasse) kon schoner (of niet) als je alle toegangspunten kunnen beheersen.

antwoordde op 17/02/2010 om 09:40
bron van user

stemmen
0

Hier is het antwoord:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
antwoordde op 18/02/2015 om 20:02
bron van user

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