Home Algoritmos y Estructuras de Datos (VJ1215)

Curso 2023/2024

Solución del ejercicio 8 del tema 3

Se proporcionan a continuación cinco soluciones:

En el tema 6 extenderemos esos tipos de recorridos para aplicarlos a grafos y los denominaremos búsqueda en anchura y búsqueda en profundidad. Los árboles binarios con los que estamos trabajando ahora son un caso particular de grafo que permite algunas simplificaciones.

Solución 1 (recursiva)

bool Conjunto::verificarProfundidad(int p) const {

   return verificarProfundidad(p, raiz);

}

bool Conjunto::verificarProfundidad(int p, Nodo * n) const {

   if (n == nullptr)
      return false;

   if (p == 0)
      return true;

   return verificarProfundidad(p - 1, n->izquierdo) || verificarProfundidad(p - 1, n->derecho);

}
	

Solución 2 (no recursiva, con cola)

#include <queue>

bool Conjunto::verificarProfundidad(int p) const {
   
   if (raiz == nullptr)
      return false;

   if (p == 0)
      return true;

   queue<Nodo *> cola;
   
   cola.push(raiz);
   int tallaNivel = 1;
   int profundidad = 0;

   while (tallaNivel > 0) {

      for (int i = 0; i < tallaNivel; i++) {
	 Nodo * nodo = cola.front();
	 cola.pop();
	 if (nodo->izquierdo != nullptr) {
	    if (profundidad + 1 == p)
	       return true;
	    cola.push(nodo->izquierdo);
	 }
	 if (nodo->derecho != nullptr) {
	    if (profundidad + 1 == p)
	       return true;
	    cola.push(nodo->derecho);
	 }
      }

      tallaNivel = cola.size();
      profundidad++;

   }

   return false;

}
	

Solución 3 (no recursiva, con cola)

#include <queue>

bool Conjunto::verificarProfundidad(int p) const {
   
   if (raiz == nullptr)
      return false;

   if (p == 0)
      return true;
   
   queue<Nodo *> cola;
   
   cola.push(raiz);
   int tallaNivel = 1;
   int profundidad = 0;

   while (! cola.empty()) {
      
      Nodo * nodo = cola.front();
      cola.pop();

      if (nodo->izquierdo != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 cola.push(nodo->izquierdo);
      }

      if (nodo->derecho != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 cola.push(nodo->derecho);
      }

      if (--tallaNivel == 0) {
	 profundidad++;
	 tallaNivel = cola.size();
      }

   }
   
   return false;

}
	

Solución 4 (no recursiva, con cola)

#include <queue>

bool Conjunto::verificarProfundidad(int p) const {
   
   if (raiz == nullptr)
      return false;

   if (p == 0)
      return true;

   struct Par {
      Nodo * nodo;
      int profundidad;
      Par(Nodo * n, int p) : nodo{n}, profundidad{p} {}
   };

   queue<Par> cola;
   
   cola.push(Par(raiz, 0));

   while (! cola.empty()) {

      Nodo * nodo = cola.front().nodo;
      int profundidad = cola.front().profundidad;
      cola.pop();

      if (nodo->izquierdo != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 cola.push(Par(nodo->izquierdo, profundidad + 1));
      }

      if (nodo->derecho != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 cola.push(Par(nodo->derecho, profundidad + 1));
      }

   }

   return false;

}
	

Esto mismo se podría hacer con dos colas en vez de una cola de pares.

Solución 5 (no recursiva, con pila)

#include <stack>

bool Conjunto::verificarProfundidad(int p) const {
   
   if (raiz == nullptr)
      return false;

   if (p == 0)
      return true;

   struct Par {
      Nodo * nodo;
      int profundidad;
      Par(Nodo * n, int p) : nodo{n}, profundidad{p} {}
   };

   stack<Par> pila;
   
   pila.push(Par(raiz, 0));

   while (! pila.empty()) {

      Nodo * nodo = pila.top().nodo;
      int profundidad = pila.top().profundidad;
      pila.pop();

      if (nodo->izquierdo != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 pila.push(Par(nodo->izquierdo, profundidad + 1));
      }

      if (nodo->derecho != nullptr) {
	 if (profundidad + 1 == p)
	    return true;
	 pila.push(Par(nodo->derecho, profundidad + 1));
      }

   }

   return false;

}
	

Esto mismo se podría hacer con dos pilas en vez de una pila de pares.