Berechnen der Höhe eines Baumes

stimmen
3

Ich versuche Höhe eines Baumes zu berechnen. Ich bin mit dem Code unten geschrieben doint.

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

}

Es gibt mir corret Ergebnis. Aber in einigen Beiträgen (gegoogelt Seite) Es wurde vorgeschlagen , eine Nachordnungsdurchquerung zu tun und diese Höhe Methode verwenden , um die Höhe zu berechnen. Einen bestimmten Grund?

Veröffentlicht am 17/02/2010 um 09:07
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
2

Die Höhe des Baumes nicht mit dem Traversal ändern. Es bleibt konstant. Es ist die Reihenfolge der Knoten, die auf dem Traversal ändern sich abhängig.

Beantwortet am 17/02/2010 um 09:17
quelle vom benutzer

stimmen
14

Aber ist das nicht ein Nachordnungsdurchquerung genau das, was Sie tun? Unter der Annahme , links und rechts sind beide nicht null, Sie zuerst tun height(left), dann height(right), und dann einige Verarbeitung in dem aktuellen Knoten. Das ist Nachordnungsdurchquerung nach mir.

Aber ich würde es so schreiben:

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

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

Edit: je nachdem wie man Baumhöhe definieren, der Basisfall (für einen leeren Baum) sollte 0 oder -1 sein.

Beantwortet am 17/02/2010 um 09:19
quelle vom benutzer

stimmen
2

Definitionen aus Wikipedia .

Preorder (depth-first):

  1. Besuchen Sie die Wurzel.
  2. Traverse den linken Unterbaum.
  3. Traverse rechten Teilbaum.

Inorder (symmetrisch):

  1. Traverse den linken Unterbaum.
  2. Besuchen Sie die Wurzel.
  3. Traverse rechten Teilbaum.

Postorder:

  1. Traverse den linken Unterbaum.
  2. Traverse rechten Teilbaum.
  3. Besuchen Sie die Wurzel.

„Besuch“ in den Definitionen bedeutet „Höhe des Knotens berechnen“. Welche in Ihrem Fall ist entweder Null (links und rechts sind null) oder 1 + kombinierte Höhe von Kindern.

In Ihrer Implementierung, spielt keine Rolle, die Traversierfolgeliste, würde es die gleichen Ergebnisse liefern. Cant sagen Sie wirklich etwas mehr als das, ohne einen Link zu Ihrer Quelle besagt, Postorder ist zu bevorzugen.

Beantwortet am 17/02/2010 um 09:27
quelle vom benutzer

stimmen
4

Der Code wird in den Bäumen scheitern, wenn mindestens einer der Knoten nur ein Kind hat:

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

Wenn der Baum zwei weitere Knoten (die Wurzel und entweder ein linkes oder rechtes Kind) die Methode auf der Root - Aufruf wird die erste Bedingung nicht erfüllen (mindestens eines der Teilbäume nicht leer ist ) , und es wird rekursiv auf beiden Kindern nennen. Einer von ihnen ist null, aber immer noch wird es dereferenzieren den Null - Zeiger das auszuführen if.

Eine richtige Lösung ist die von gepostet Hans hier. Auf jeden Fall müssen Sie entscheiden , was Ihre Methode Invarianten werden: entweder Sie erlauben Anrufe , bei denen das Argument null ist und Sie damit umgehen , dass anmutig oder auch das Argument erfordern nicht-null und garantiert sein , dass Sie die Methode nicht mit Null - Zeiger aufrufen .

Der erste Fall ist sicherer , wenn Sie nicht alle Einstiegspunkte steuern können (das Verfahren , wie in Ihrem Code öffentlich ist) , da Sie nicht garantieren können , dass die externe Code nicht Null - Zeiger übergeben wird. Die zweite Lösung (die Signatur Bezug zu ändern, und es ein Element Methode der Herstellung treeKlasse) könnte saubere (oder nicht), wenn Sie alle Eintrittspunkte steuern.

Beantwortet am 17/02/2010 um 09:40
quelle vom benutzer

stimmen
0

Hier ist die Antwort:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
Beantwortet am 18/02/2015 um 20:02
quelle vom benutzer

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