Árbol de búsqueda binaria

Harshit Jindal 12 octubre 2023
  1. Operación de búsqueda en el Árbol binario de búsqueda
  2. Algoritmo de búsqueda BST
  3. Ilustración de búsqueda BST
  4. Inserción en BST
  5. Algoritmo de inserción BST
  6. Ilustración de inserto BST
  7. Implementación de búsqueda e inserción de BST
  8. Complejidad del algoritmo de inserción y búsqueda de BST
Árbol de búsqueda binaria

El Árbol binario de búsqueda (BST) es una estructura de datos de árbol binario ordenada basada en nodos. Los nodos tienen un valor y dos nodos secundarios (un árbol binario tiene un máximo de dos nodos secundarios) adjuntos a la izquierda y a la derecha. A excepción del nodo raíz, solo su padre puede hacer referencia a todos los nodos. Un BST tiene las siguientes propiedades:

  • Todos los nodos del subárbol izquierdo son más pequeños que el nodo raíz.
  • Todos los nodos del subárbol derecho son más grandes que el nodo raíz.
  • Los subárboles izquierdo y derecho también deben ser árboles de búsqueda binarios.

Ejemplo de Árbol binario de búsqueda

El árbol de la izquierda satisface todas las propiedades de BST. Por otro lado, el árbol del lado derecho parece ser un BST ya que todos los nodos del subárbol izquierdo son más pequeños y los del subárbol derecho son más grandes. Pero el nodo 1 en el subárbol izquierdo no satisface las propiedades de BST ya que es más pequeño que el nodo 4 pero no mayor que el nodo raíz 3. Por lo tanto, no es un BST.

Dado que se trata de una estructura de datos ordenada, los elementos introducidos siempre se organizan de forma ordenada. Podemos utilizar el recorrido en orden para recuperar los datos almacenados en BST en orden ordenado. Recibe su nombre porque, al igual que la búsqueda binaria, se puede utilizar para buscar los datos en O(logn).

Operación de búsqueda en el Árbol binario de búsqueda

Sabemos que en una BST, todos los elementos del lado derecho de la raíz son más grandes y, por lo tanto, si el elemento de destino que estamos buscando es más pequeño que la raíz, se puede descuidar todo el subárbol derecho. De manera similar, si el elemento es más grande que la raíz, el subárbol izquierdo puede despreciarse. Nos movemos de manera similar hasta que agotamos el árbol o encontramos el elemento de destino como raíz del subárbol. Si el BST está balanceado (un árbol se llama árbol balanceado si para todos los nodos la diferencia entre la altura del subárbol izquierdo y derecho es menor que igual a 1), entonces la búsqueda dentro de BST se realiza de manera similar a la búsqueda binaria ya que ambos los subárboles tienen alrededor de la mitad de los elementos que se descuidan en cada iteración, pero en el caso de un árbol desequilibrado, todos los nodos pueden estar presentes en el mismo lado y la búsqueda puede funcionar de manera similar a la búsqueda lineal.

Algoritmo de búsqueda BST

Sea raíz el nodo raíz de BST y X el elemento de destino que se busca.

  • Si root == NULL, devuelve NULL;
  • Si X == root->data, devuelve root;
  • Si X < root->data, devuelve search(root->left)
  • Si X > root->data, devuelve search(root->right)

Ilustración de búsqueda BST

Paso de búsqueda binaria

Supongamos que tenemos el BST anterior y queremos encontrar el elemento X = 25.

  • Compara el elemento raíz con X para encontrar que 41 > 25, así que descarta la mitad derecha y cambia al subárbol izquierdo.
  • La raíz del subárbol izquierdo 23 < 25, por lo tanto, descarta su subárbol izquierdo y muévete hacia la derecha.
  • La nueva raíz 28 < 25, así que muévete hacia la izquierda y encuentra nuestro elemento X es igual a 25 y devuelve el nodo.

Inserción en BST

El algoritmo para insertar un elemento dentro de BST es bastante similar a buscar un elemento dentro de BST porque antes de insertar un elemento, tenemos que encontrar su posición correcta. La única diferencia en la función de inserción y búsqueda es que en el caso de la búsqueda, devolvemos el nodo que contiene el valor objetivo, mientras que creamos un nuevo nodo en la posición apropiada del nodo en el caso de una inserción.

Algoritmo de inserción BST

Sea raíz el nodo raíz de BST y X el elemento que queremos insertar.

  • Si root == NULL, devuelve un nodo recién formado con data = X
  • if (X < root->data), root->left = insert(root->left, X);
  • else if (X > root->data), root->right = insert(root->right, X);
  • devuelve un puntero a la raíz original;

Ilustración de inserto BST

Ilustración de inserto BST

  • Primero, inicializamos BST creando un nodo raíz e insertamos 5 en él.
  • 3 es menor que 5 por lo que se inserta a la izquierda de 5.
  • 4 es menor que 5 pero mayor que 3, por lo que se inserta a la derecha de 3 pero a la izquierda de 4.
  • 2 es el elemento más pequeño en el árbol actual, por lo que se inserta en la posición más a la izquierda.
  • 1 es el elemento más pequeño en el árbol actual, por lo que se inserta en la posición más a la izquierda.
  • 6 es el elemento más grande en el árbol actual, por lo que se inserta en la posición más a la derecha.

Así es como insertamos elementos dentro de una BST.

Implementación de búsqueda e inserción de BST

#include <iostream>
using namespace std;

class Node {
 public:
  int key;
  Node *left, *right;
};

Node *newNode(int item) {
  Node *temp = (Node *)malloc(sizeof(Node));
  temp->key = item;
  temp->left = temp->right = NULL;
  return temp;
}

void inorder(Node *root) {
  if (root != NULL) {
    inorder(root->left);
    cout << root->key << " ";
    inorder(root->right);
  }
}

Node *insert(Node *root, int key) {
  if (root == NULL) return newNode(key);
  if (key < root->key)
    root->left = insert(root->left, key);
  else
    root->right = insert(root->right, key);

  return root;
}

Node *search(Node *root, int key) {
  if (root == NULL || root->key == key) return root;

  if (root->key < key) return search(root->right, key);

  return search(root->left, key);
}
int main() {
  Node *root = NULL;
  root = insert(root, 5);
  root = insert(root, 3);
  root = insert(root, 8);
  root = insert(root, 6);
  root = insert(root, 4);
  root = insert(root, 2);
  root = insert(root, 1);
  root = insert(root, 7);
  cout << search(root, 5)->key << endl;
}

Complejidad del algoritmo de inserción y búsqueda de BST

Complejidad del tiempo

  • Caso promedio

En el caso promedio, la complejidad temporal de insertar un nodo o buscar un elemento en una BST es del orden de la altura del Árbol binario de búsqueda. En promedio, la altura de un BST es O(logn). Ocurre cuando la BST formada es una BST equilibrada. Por tanto, la complejidad del tiempo es del orden de [Big Theta]: O(logn).

  • Mejor caso

El mejor de los casos ocurre cuando el árbol es una BST equilibrada. La complejidad de tiempo de inserción y búsqueda en el mejor de los casos es del orden de O(logn). Es lo mismo que la complejidad del tiempo promedio de los casos.

  • Peor caso

En el peor de los casos, podríamos tener que atravesar desde la raíz hasta el nodo de la hoja más profundo, es decir, toda la altura h del árbol. Si el árbol está desequilibrado, es decir, está sesgado, la altura del árbol puede convertirse en n y, por lo tanto, la complejidad temporal en el peor de los casos tanto de la operación de inserción como de la operación de búsqueda es O(n).

Complejidad espacial

La complejidad espacial de la operación de inserción y búsqueda es O(n) debido al espacio requerido por las llamadas recursivas.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Artículo relacionado - Data Structure

Artículo relacionado - Binary Tree

Artículo relacionado - Binary Search Tree