Calcula la altura de un árbol

votos
3

Estoy tratando de calcular la altura de un árbol. Estoy doint con el código escrito abajo.

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

}

Me da resultado corret. Sin embargo, en algunos mensajes (página buscado en Google) Se propuso hacer un recorrido en orden posterior y utilizar este método altura para calcular la altura. Cualquier razón específica?

Publicado el 17/02/2010 a las 09:07
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
2

La altura del árbol no cambia con el recorrido. Se mantiene constante. Es la secuencia de los nodos que cambian dependiendo de la travesía.

Respondida el 17/02/2010 a las 09:17
fuente por usuario

votos
14

Pero no es un recorrido en orden posterior, precisamente, lo que está haciendo? Suponiendo izquierda y derecha son tanto no nulo, primero hacer height(left), entonces height(right), y luego algún tipo de procesamiento en el nodo actual. Eso es transversal orden posterior en mi opinión.

Pero lo escribiría así:

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

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

Editar: dependiendo de cómo se defina la altura del árbol, el caso base (por un árbol vacío) debe ser 0 o -1.

Respondida el 17/02/2010 a las 09:19
fuente por usuario

votos
2

Definiciones de Wikipedia .

Preorder (profundidad-primero):

  1. Visita la raíz.
  2. Recorrer el subárbol izquierdo.
  3. Recorrer el subárbol derecho.

Inorder (simétrico):

  1. Recorrer el subárbol izquierdo.
  2. Visita la raíz.
  3. Recorrer el subárbol derecho.

Orden de publicación:

  1. Recorrer el subárbol izquierdo.
  2. Recorrer el subárbol derecho.
  3. Visita la raíz.

"Visita" en las definiciones significa "calcular altura de nodo". Que en su caso es cero (izquierda y derecha son nulas) o 1 + altura combinada de los niños.

En su aplicación, el orden transversal no importa, que daría los mismos resultados. Realmente no puedo decirle nada más que eso sin un enlace a la fuente afirmando orden posterior es preferir.

Respondida el 17/02/2010 a las 09:27
fuente por usuario

votos
4

El código fallará en los árboles de los que al menos uno de los nodos tiene un solo hijo:

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

Si el árbol tiene dos nodos (la raíz y, o bien un niño izquierda o derecha) llamando al método de la raíz no cumpla la primera condición (al menos uno de los subárboles no está vacío) y se le llamará de forma recursiva a ambos niños. Uno de ellos es nula, pero aún así será eliminar la referencia al puntero nulo para realizar el if.

Una solución correcta es la publicada por Hans aquí. En todo caso hay que elegir cuáles son sus invariantes método son: o se permiten llamadas donde el argumento es nulo y manejar que con gracia o de lo contrario se necesita el argumento sea no nulo y la garantía de que no se llama el método con punteros nulos .

El primer caso es más seguro si usted no controla todos los puntos de entrada (el método es público como en su código), ya que no se puede garantizar que el código externo no va a pasar punteros nulos. La segunda solución (cambios en la firma de referencia, y por lo que es un método miembro de la treeclase) podría estar más limpio (o no) si se puede controlar todos los puntos de entrada.

Respondida el 17/02/2010 a las 09:40
fuente por usuario

votos
0

Aquí está la respuesta:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}
Respondida el 18/02/2015 a las 20:02
fuente por usuario

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