2010-04-08 27 views
41

Me preguntaba si alguien podría ayudarme a volver a trabajar este método para encontrar la altura de un árbol de búsqueda binario. Hasta ahora, mi código se ve así. Sin embargo, la respuesta que recibo es más grande que la altura real en 1. Pero cuando elimino el +1 de mis declaraciones de devolución, es menos que la altura real en 1. Todavía estoy tratando de ajustar mi cabeza a la recursión con estos BST. Cualquier ayuda sería muy apreciada.Encontrando altura en Árbol de búsqueda binaria

public int findHeight(){ 
    if(this.isEmpty()){ 
     return 0; 
    } 
    else{ 
     TreeNode<T> node = root; 
     return findHeight(node); 
    } 
} 
private int findHeight(TreeNode<T> aNode){ 
    int heightLeft = 0; 
    int heightRight = 0; 
    if(aNode.left!=null) 
     heightLeft = findHeight(aNode.left); 
    if(aNode.right!=null) 
     heightRight = findHeight(aNode.right); 
    if(heightLeft > heightRight){ 
     return heightLeft+1; 
    } 
    else{ 
     return heightRight+1; 
    } 
} 
+0

Bueno, tengo que volver a la altura correcta devolviendo findHeight (nodo) -1 en mi método público. Sin embargo, siento que este es un código descuidado, ¿alguna sugerencia sobre una renovación? – mike

+0

¿Es este el enfoque correcto para resolver la altura del árbol? Https: //github.com/joeyajames/Python/issues/1 – rittam

Respuesta

75

El problema radica en su funda base.

"La altura de un árbol es la longitud de la ruta desde la raíz hasta el nodo más profundo del árbol. Un árbol (rooteado) con solo un nodo (la raíz) tiene una altura de cero." - Wikipedia

Si no hay un nodo, quiere devolver -1 no 0. Esto se debe a que está agregando 1 al final.

Entonces, si no hay un nodo, devuelve -1 que anula el +1.

int findHeight(TreeNode<T> aNode) { 
    if (aNode == null) { 
     return -1; 
    } 

    int lefth = findHeight(aNode.left); 
    int righth = findHeight(aNode.right); 

    if (lefth > righth) { 
     return lefth + 1; 
    } else { 
     return righth + 1; 
    } 
} 
+1

Sí, esto funciona correctamente sin tener que restar 1 en mi método público. Todavía estoy confundido sobre cómo funciona este método con la recursión. Decidí enteros a la izquierda y a la derecha después de la instrucción if, pero no entiendo cómo se incrementan con este método – mike

+1

Este método funciona restando 1 en el caso base, se incrementan como cualquier otro método dado, cuando se profundiza en el árbol agregas 1 a la altura. – Corey

+0

dónde encontraste tu cita 'La altura de un árbol es la longitud de la ruta desde la raíz hasta el nodo más profundo del árbol. Un árbol (rooteado) con solo un nodo (la raíz) tiene una altura de cero'? En la página wiki, no existe tal cita –

3

Aquí está una manera concisa y es de esperar correcta de expresarlo:

private int findHeight(TreeNode<T> aNode){ 
    if(aNode == null || (aNode.left == null && aNode.right == null)) 
     return 0; 
    return Math.max(findHeight(aNode.left), findHeight(aNode.right)) + 1; 
    } 

Si el nodo actual es nulo, no hay árbol. Si ambos hijos están, hay una sola capa, lo que significa 0 altura. Esto usa la definición de altura (mencionada por Stephen) como # de capas - 1

8

IMO, su código se beneficiaría de ser simplificado un poco. En lugar de intentar finalizar la recursión cuando un puntero secundario es nulo, solo finalícelo cuando el puntero actual sea nulo. Eso hace que el código sea lote más fácil de escribir. En pseudo-código que se ve algo como esto:

if (node = null) 
    return 0; 
else 
    left = height(node->left); 
    right = height(node->right); 
    return 1 + max(left, right); 
+1

No se puede llamar a un método en un objeto nulo :) – jemfinch

+4

@jemfinch, ¿a dónde está llamando? en un objeto nulo, ¿no es eso para lo que es el caso base? – Corey

+1

@jemfinch: ¡Creo que es algo bueno que no haya sugerido hacer tal cosa! –

29

La altura de un árbol de búsqueda binaria es igual a number of layers - 1.

Ver el diagrama de la http://en.wikipedia.org/wiki/Binary_tree

su recursividad es bueno, por lo que sólo resta uno en el nivel raíz.

También tenga en cuenta, se puede limpiar la función un poco por el manejo de los nodos nulos:

int findHeight(node) { 
    if (node == null) return 0; 
    return 1 + max(findHeight(node.left), findHeight(node.right)); 
} 
+0

Mi primer intento con este método utilicé algo en este sentido, pero seguí obteniendo una excepción de StackOverFlow por algún motivo cuando ejecuté mi código. Estoy asumiendo porque verifico si los punteros apuntan a nulo. – mike

+0

(Se eliminó el comentario sobre C++, que no se aplica). Es probable que su "nodo == nulo" no termine correctamente. – Stephen

+0

Stephen, ¿no debería ser 0 para un árbol de nodo único? Esto devuelve 1. –

2

Esto no se ha probado, pero bastante obvio correcta:

 
private int findHeight(Treenode aNode) { 
    if (aNode.left == null && aNode.right == null) { 
    return 0; // was 1; apparently a node with no children has a height of 0. 
    } else if (aNode.left == null) { 
    return 1 + findHeight(aNode.right); 
    } else if (aNode.right == null) { 
    return 1 + findHeight(aNode.left); 
    } else { 
    return 1 + max(findHeight(aNode.left), findHeight(aNode.right)); 
    } 
} 

A menudo la simplificación de su código es más fácil que averiguar por qué está apagado por uno. Este código es fácil de entender: los cuatro casos posibles están claramente manejados de una manera obviamente correcta:

  • Si tanto los árboles izquierdo y derecho son nulos, devuelve 1, ya que un solo nodo, por definición, tiene una altura de 1
  • Si los árboles izquierdo o derecho (pero no ambos) son nulos, devuelve la altura del árbol no nulo, más 1 para tener en cuenta la altura agregada del nodo actual.
  • Si ninguno de los árboles es nulo, devuelva la altura del subárbol más alto, de nuevo más uno para el nodo actual.
+0

Este código funciona, y es más claro que lo que tenía sin embargo, todavía está devolviendo la altura +1. En mi libro, la altura se define como la longitud del camino desde la raíz hasta su hoja más profunda. Entonces, según entiendo, una BST que contenga 15, 25, 30, 45 (en este orden) tendría una altura de solo 3 correctas? – mike

+0

En realidad, un árbol con solo el nodo raíz tiene una altura de 0 no 1. – Corey

+1

Extraño. Realmente no debería llamarse "altura" si lo que realmente quieren decir es "caminos para descender", pero esa parece ser la terminología estándar, desafortunadamente. La forma correcta de corregir esto es cambiar el primer caso (node.left == null && node.right == null) para devolver 0. – jemfinch

2
public void HeightRecursive() 
    { 
     Console.WriteLine(HeightHelper(root)); 
    } 

    private int HeightHelper(TreeNode node) 
    { 
     if (node == null) 
     { 
      return -1; 
     } 
     else 
     { 
      return 1 + Math.Max(HeightHelper(node.LeftNode),HeightHelper(node.RightNode));   
     } 
    } 

código C#. Incluye estos dos métodos en tu clase BST. necesitas dos métodos para calcular la altura del árbol. HeightHelper lo calcula, & HeightRecursive imprímelo en main().

1

La definición dada anteriormente de la altura es incorrecta. Esa es la definición de la profundidad.

"La profundidad de un nodo M en un árbol es la longitud del camino desde la raíz del árbol para M. La altura de un árbol es uno más que la profundidad del nodo más profundo en el Todos los nodos de profundidad d están en el nivel d en el árbol. La raíz es el único nodo en el nivel 0, y su profundidad es 0. "

Cita: "Una Introducción Práctica a la Estructura de Datos y Análisis Algoritmo" Edition 3.2 (Java Version) Clifford A. Shaffer Departamento de Informática Virginia Tech Blacksburg, VA 24061

-1

Para cualquier persona otra cosa que dice esto !!!!

ALTURA se define como la cantidad de nodos en la ruta más larga desde el nodo raíz a un nodo hoja. Por lo tanto: un árbol con solo un nodo raíz tiene una altura de 1 y no 0.

El NIVEL de un nodo dado es la distancia desde la raíz más 1. Por lo tanto: la raíz está en el nivel 1, sus nodos secundarios son en el nivel 2 y así sucesivamente.

(Información cortesía de Data Structures: Abstraction and Design Using Java, 2nd Edition, por Elliot B. Koffman & Paul A. Wolfgang) - Libro utilizado en el curso de Data Structures que estoy cursando actualmente en Columbus State University.

+4

PARA CUALQUIER OTRA PERSONA QUE LEA ESTO !!!! ¡Esta definición de altura es incorrecta! La altura de un árbol es la cantidad de ** bordes ** desde el nodo raíz hasta el nodo de hoja más alejado (o uno de los más lejanos si hay varias hojas equidistantes). Como son bordes, un árbol con solo un nodo raíz tendrá una altura de cero. Vaya a https://en.wikipedia.org/wiki/Tree_(data_structure)#Definition y lea "Altura del nodo" y "Altura del árbol".Además, tanto los libros de texto de algoritmos de Cormen como los de Weiss respaldan esta definición. La definición dada de nivel es correcta. –

0

supongo que esta pregunta podría significar dos cosas diferentes ...

  1. La altura es el número de nodos en la rama más larga: -

    int calcHeight(node* root){ if(root==NULL) return 0; int l=calcHeight(root->left); int r=calcHeight(root->right); if(l>r) return l+1; else return r+1; }

  2. Altura es la número total de nodos en el árbol sí mismo:

    int calcSize(node* root){ if(root==NULL) return 0; return(calcSize(root->left)+1+calcSize(root->right)); }

0
public int getHeight(Node node) 
{ 
    if(node == null) 
     return 0; 

    int left_val = getHeight(node.left); 
    int right_val = getHeight(node.right); 
    if(left_val > right_val) 
     return left_val+1; 
    else 
     return right_val+1; 
} 
0

Aquí es una solución en C#

private static int height_Tree(Node root) 
    { 
     if (root == null) 
     { 
      return 0; 
     } 

     int left = 1 + height_Tree(root.left); 
     int right = 1 + height_Tree(root.right); 

     return Math.Max(left, right); 
    } 
15
int getHeight(Node node) { 
if (node == null) return -1; 

return 1 + Math.max(getHeight(node.left), getHeight(node.right)); 
} 
0

Establecer un tempHeight como una variable estática (inicialmente 0).

estática findHeight vacío (nodo Nodo, int count) {

if (node == null) { 
     return; 
    } 
    if ((node.right == null) && (node.left == null)) { 
     if (tempHeight < count) { 
      tempHeight = count; 

     } 

    } 

    findHeight(node.left, ++count); 
    count--; //reduce the height while traversing to a different branch 
    findHeight(node.right, ++count); 

} 
0

Aquí es una solución en Java un poco largo, pero funciona ..

public static int getHeight (Node root){ 
    int lheight = 0, rheight = 0; 
    if(root==null) { 
     return 0; 
    } 
    else { 
     if(root.left != null) { 
      lheight = 1 + getHeight(root.left); 
      System.out.println("lheight" + " " + lheight); 
     } 
     if (root.right != null) { 
      rheight = 1+ getHeight(root.right); 
      System.out.println("rheight" + " " + rheight); 
     } 
     if(root != null && root.left == null && root.right == null) { 
      lheight += 1; 
      rheight += 1; 
     } 

    } 
    return Math.max(lheight, rheight); 
    } 
3
class Solution{ 
    public static int getHeight(Node root) { 
     int height = -1; 

     if (root == null) { 
      return height; 
     } else { 
      height = 1 + Math.max(getHeight(root.left), getHeight(root.right)); 
     } 

     return height; 
    } 
0
int getHeight(Node* root) 
{ 
    if(root == NULL) return -1; 
    else    return max(getHeight(root->left), getHeight(root->right)) + 1; 
} 
1
public int height(){ 

    if(this.root== null) return 0; 

    int leftDepth = nodeDepth(this.root.left, 1); 
    int rightDepth = nodeDepth(this.root.right, 1); 

    int height = leftDepth > rightDepth? leftDepth: rightDepth; 

    return height; 
} 


private int nodeDepth(Node node, int startValue){ 

    int nodeDepth = 0; 

    if(node.left == null && node.right == null) return startValue; 
    else{ 
     startValue++; 
     if(node.left!= null){ 
      nodeDepth = nodeDepth(node.left, startValue); 
     } 

     if(node.right!= null){ 
      nodeDepth = nodeDepth(node.right, startValue); 
     } 
    } 

    return nodeDepth; 
} 
2

Para personas como yo a quienes les gustan las soluciones de una línea:

public int getHeight(Node root) { 
    return Math.max(root.left != null ? getHeight(root.left) : -1, 
        root.right != null ? getHeight(root.right) : -1) 
        + 1; 
} 
0

// función para encontrar la altura de la BST

int height(Node* root) { 
    if(root == NULL){ 
     return -1; 
    } 

    int sum=0; 
    int rheight = height(root->right); 
    int lheight = height(root->left); 

    if(lheight>rheight){ 
     sum = lheight +1; 
    } 
    if(rheight > lheight){ 
     sum = rheight + 1; 
    } 

    return sum; 
} 
Cuestiones relacionadas