Encontrar si un Árbol Binario es un Árbol de Búsqueda Binario [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Hoy tuve una entrevista donde me pidieron que escribiera un programa que toma un Árbol Binario y devuelve verdadero si también es un Árbol de Búsqueda Binario de lo contrario es falso.

Mi Approach1: Realizar un recorrido en orden y almacenar los elementos en O (n) tiempo. Ahora explore a través de la matriz/lista de elementos y compruebe si el elemento en ith índice es mayor que el elemento en (i+1)th índice. Si se encuentra tal condición, devuelva false y salga del bucle. (Esto toma O(n) tiempo). Al final devuelve true.

Pero este caballero quería que le diera una solución eficiente. Lo intenté pero no tuve éxito, porque para encontrar si es un BST tengo que comprobar cada nodo.

Además me estaba señalando para pensar recursión. Mi enfoque 2: Un BT es un BST si para cualquier nodo N N - > left es right > N, y el sucesor en orden del nodo izquierdo de N es menor que N y el sucesor en orden del nodo derecho de N es mayor que N y los subárboles izquierdo y derecho son BSTs.

Pero esto va a ser complicado y el tiempo de ejecución no parece ser bueno. Por favor, ayuda si conoces alguna solución óptima.

Author: alex, 2012-05-31

7 answers

Es un problema bastante conocido con la siguiente respuesta:

public boolean isValid(Node root) {
     return isValidBST(root, Integer.MIN_VALUE,
          Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
     if(node == null)
         return true;
     return node.value > l 
         && node.value < h
         && isValidBST(node.left, l, node.value)
         && isValidBST(node.right, node.value, h);
}

La llamada recursiva se asegura de que los nodos del subárbol estén dentro del rango de sus ancestros, lo cual es importante. La complejidad del tiempo de ejecución será O (n) ya que cada nodo se examina una vez.

La otra solución sería hacer un recorrido por orden y verificar si la secuencia está ordenada, especialmente porque ya sabe que se proporciona un árbol binario como entrada.

 77
Author: Dhruv Gairola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-02 19:50:47

La respuesta proporcionada por @Dhruv es buena. Además de eso, aquí hay otra solución que funciona en O (n) tiempo.
Necesitamos hacer un seguimiento del nodo anterior en este enfoque. En cada llamada recursiva comprobamos los datos del nodo anterior con los datos del nodo actual. Si los datos del nodo actual son menores que los anteriores, devolvemos false

int isBST(node* root) {
  static node* prev  = NULL;

  if(root==NULL)
    return 1;

  if(!isBST(root->left))
    return 0;

  if(prev!=NULL && root->data<=prev->data)
    return 0;

  prev = root;
  return isBST(root->right);
}

 7
Author: AgentX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-28 14:01:33
boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
  if(node == null){
    return true;
  }

  boolean left  = isBinarySearchTree(node.getLeft(), min, node.getValue());
  boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);

  return left && right && (node.getValue()<max) && (node.getValue()>=min);      
}

Se invita a formular observaciones. Gracias.

 1
Author: Trying,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-28 14:06:45

Creo que el segundo enfoque es correcto. El árbol puede ser atravesado de manera recursiva. En cada iteración se pueden almacenar los límites inferior y superior del subárbol actual. Si queremos comprobar el subárbol con raíz x, y los límites para el subárbol son l y h, entonces todo lo que necesitamos es comprobar que l

Esto tendrá complejidad O(n), porque comenzamos desde la raíz y cada nodo se comprueba solo una vez como raíz de algún subárbol. Además, necesitamos memoria O (h) para llamadas recursivas, donde h es la altura del árbol.

 0
Author: fdermishin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 11:33:21

Hay algunos ejemplos anteriores usando INTEGER.MAX Y MIN No veo una razón para pasarlos y el significado de ello, corrígeme si me equivoco de alguna manera o explícame la razón.

More over binary search tree puede tener objetos que son comparados por el método compareTo o Coperator.. (de ahí Entero.MIN e Integer.MAX no encaja en ese modelo) Estoy escribiendo un código donde devuelve verdadero o falso uno tiene que llamar (root_node, true) y devolverá true si es un bst else false

void boolean isBSt( node root_node, boolean passed_root)
{

  if ( node==null){
        if ( passed_root)
        return false;
        // you have passed null pointer as 
        //root of the tree , since there is no 
        // valid start point we can throw an exception or return false      
        return true;
   }

  if( node.right !=null ) 
     if ( node.right.data <= node.data)
   return false;

  if ( node.left !=null ) 
        if ! ( node.left.data <= node.data) 
    return false;

  return ( isBST( node.right , false) && isBST( node.left, false ) )

}
 -1
Author: user2398113,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-21 18:11:19

Echa un vistazo a esta solución: http://preparefortechinterview.blogspot.com/2013/09/am-i-bst.html

Explica diferentes maneras y le da un método genérico y eficiente también. Espero que ayude.

 -1
Author: Furquan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 00:01:44

Aquí hay otra Solución que usa 2 funciones auxiliares para calcular para cada nodo el valor mínimo y máximo en el subárbol usando las funciones auxiliares MinValue y MaxValue

int isBST(struct node* node)
    {
      if (node == NULL)
        return(true); 

      /* false if the max of the left is > than us */
        if (node->left!=NULL && maxValue(node->left) > node->data)
            return(false); 

      /* false if the min of the right is <= than us */
        if (node->right!=NULL && minValue(node->right) < node->data)
            return(false); 

      /* false if, recursively, the left or right is not a BST */ 
         if (!isBST(node->left) || !isBST(node->right))
           return(false); 

      /* passing all that, it's a BST */
          return(true);
    }
 -2
Author: Sanil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-28 14:07:37