From d8c6d769f1f7d23ac8ce30706c899cac250ab089 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Sun, 11 May 2025 20:40:30 -0300 Subject: [PATCH 01/10] Se agrego al gitignore archivos con extension .excalidraw --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 17a4914..dc72967 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ cmake-build-debug/ .idea/ build/ + +# Excalidraw files +*.excalidraw From 4057cc5fa005e8bea08fa6a7e5e266bbdc1e1497 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Wed, 14 May 2025 15:27:17 -0300 Subject: [PATCH 02/10] Se va a implementar un arbol binario de decision para modelar la logica con la que los NPC mercader toman decisiones de interaccion con el jugador basadas en condiciones internas. Para esto implemte la clase DecisionTree, con la cual se va a crear un Arbol Binario, con nodos con datos de tipo string. Esta clase tambien implementa metodos para buscar decisiones, eliminar, consultar si esta vacio y recorrerlo en preorden. Tambien cuenta con un destructor el cual elimina los nodos del arbol y libera memoria correctamente. --- include/decisionTree.hpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 include/decisionTree.hpp diff --git a/include/decisionTree.hpp b/include/decisionTree.hpp new file mode 100644 index 0000000..3345f13 --- /dev/null +++ b/include/decisionTree.hpp @@ -0,0 +1,31 @@ +#include + +struct Nodo { + std::string decision; + Nodo* izquierda; + Nodo* derecha; + + Nodo(const std::string& d) + : decision(d), izquierda(nullptr), derecha(nullptr) {} +}; + +class DecisionTree { +public: + DecisionTree(); + ~DecisionTree(); + + void insertar(const std::string& decision); + bool buscar(const std::string& decision) const; + void eliminar(const std::string& decision); + bool estaVacio() const; + void recorrerPreorden() const; + +private: + Nodo* raiz; + + void insertar(Nodo*& nodo, const std::string& decision); + bool buscar(Nodo* nodo, const std::string& decision) const; + void eliminarNodo(Nodo*& nodo, const std::string& decision); + void recorrerPreorden(Nodo* nodo) const; + void destruir(Nodo* nodo); +}; From ea833817d797f32c420f936c047e8216f373c126 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Wed, 14 May 2025 15:38:42 -0300 Subject: [PATCH 03/10] Agregue el constructor y destructor a la clase DecisionTree --- src/decisionTree.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/decisionTree.cpp diff --git a/src/decisionTree.cpp b/src/decisionTree.cpp new file mode 100644 index 0000000..b373319 --- /dev/null +++ b/src/decisionTree.cpp @@ -0,0 +1,38 @@ +#include "decisionTree.hpp" + +DecisionTree::DecisionTree() { + raiz = nullptr; +} + + + +// Metodos publicos +void DecisionTree::insertar(const std::string& decision) { + insertar(raiz, decision); +} + +DecisionTree::~DecisionTree() { + destruir(raiz); +} + + + +// Metodos privados +void DecisionTree::insertar(Nodo*& nodo, const std::string& decision) { + // nodo va a ser la raiz del arbol + + if(nodo == nullptr) { + nodo = new Nodo(decision); + } + + if(decision < nodo->decision) insertar(nodo->izquierda, decision); + if(decision > nodo->decision) insertar(nodo->derecha, decision); +} + + +void DecisionTree::destruir(Nodo* nodo) { + if(!nodo) return; + destruir(nodo->izquierda); + destruir(nodo->derecha); + delete nodo; +} From 08f24ddd7a6611a29b4f2b110e699bc96733de7d Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Wed, 14 May 2025 16:04:36 -0300 Subject: [PATCH 04/10] Implemente el metodo insertar, aplicando recursividad para respetar el orden lexicografico. Implemente el metodo eliminar, respetando la jerarquia que queda luego en el arbol, para esto implemente una funcion auxiliar encontrarMinimo. --- include/decisionTree.hpp | 1 + src/decisionTree.cpp | 51 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/decisionTree.hpp b/include/decisionTree.hpp index 3345f13..56e3d14 100644 --- a/include/decisionTree.hpp +++ b/include/decisionTree.hpp @@ -28,4 +28,5 @@ class DecisionTree { void eliminarNodo(Nodo*& nodo, const std::string& decision); void recorrerPreorden(Nodo* nodo) const; void destruir(Nodo* nodo); + Nodo* encontrarMinimo(Nodo* nodo); }; diff --git a/src/decisionTree.cpp b/src/decisionTree.cpp index b373319..be1294c 100644 --- a/src/decisionTree.cpp +++ b/src/decisionTree.cpp @@ -4,6 +4,9 @@ DecisionTree::DecisionTree() { raiz = nullptr; } +DecisionTree::~DecisionTree() { + destruir(raiz); +} // Metodos publicos @@ -11,12 +14,10 @@ void DecisionTree::insertar(const std::string& decision) { insertar(raiz, decision); } -DecisionTree::~DecisionTree() { - destruir(raiz); +void DecisionTree::eliminar(const std::string& decision) { + eliminarNodo(raiz, decision); } - - // Metodos privados void DecisionTree::insertar(Nodo*& nodo, const std::string& decision) { // nodo va a ser la raiz del arbol @@ -36,3 +37,45 @@ void DecisionTree::destruir(Nodo* nodo) { destruir(nodo->derecha); delete nodo; } + +void DecisionTree::eliminarNodo(Nodo*& nodo, const std::string& decision) { + if(!nodo) return; + + if(decision < nodo->decision) { + eliminarNodo(nodo->izquierda, decision); + } else if (decision > nodo->decision) { + eliminarNodo(nodo->derecha, decision); + } else { + // Caso 1: El nodo a eliminar NO tiene hijos + if(!nodo->izquierda && !nodo->derecha) { + delete nodo; + nodo = nullptr; + } + + // Caso 2: El nodo a eliminar tiene UN SOLO hijo + else if(!nodo->izquierda) { + Nodo* temp = nodo; + nodo = nodo->derecha; + delete temp; + } else if(!nodo->derecha) { + Nodo* temp = nodo; + nodo = nodo->izquierda; + delete temp; + } + + // Caso 3: El nodo a eliminar tiene DOS hijos + else { + Nodo* sucesor = encontrarMinimo(nodo->derecha); + nodo->decision = sucesor->decision; + eliminarNodo(nodo->derecha, sucesor->decision); + } + + } +} + +Nodo* DecisionTree::encontrarMinimo(Nodo* nodo) { + while(nodo && nodo->izquierda) { + nodo = nodo->izquierda; + } + return nodo; +} From aee216568212b7df18bd60156fdb55eea3a66b19 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Wed, 14 May 2025 16:09:21 -0300 Subject: [PATCH 05/10] Implemente la funcion buscar, la cual busca una condicion, indicada por parametro, en el arbol. Retorna true si la encuentra, y false si no la encuentra. Se utiliza recursion para ir recorriendo el arbol. --- src/decisionTree.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/decisionTree.cpp b/src/decisionTree.cpp index be1294c..e7e3eca 100644 --- a/src/decisionTree.cpp +++ b/src/decisionTree.cpp @@ -18,6 +18,10 @@ void DecisionTree::eliminar(const std::string& decision) { eliminarNodo(raiz, decision); } +bool DecisionTree::buscar(const std::string& decision) const { + return buscar(raiz, decision); +} + // Metodos privados void DecisionTree::insertar(Nodo*& nodo, const std::string& decision) { // nodo va a ser la raiz del arbol @@ -79,3 +83,18 @@ Nodo* DecisionTree::encontrarMinimo(Nodo* nodo) { } return nodo; } + +bool DecisionTree::buscar(Nodo* nodo, const std::string& decision) const { + + if(!nodo) { + return false; + } + + if(nodo->decision == decision) { + return true; + } + + return buscar(nodo->izquierda, decision) || buscar(nodo->derecha, decision); +} + + From df1c76d7a6ae43c509843dab4419a39b93416536 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Wed, 14 May 2025 16:15:17 -0300 Subject: [PATCH 06/10] Implemente el metodo estaVacio, el cual indica si el arbol esta vacio no, dependiendo de si la raiz es null o no. Si es null es que aun no se han agregado decisiones al arbol, por ende esta vacio. Tambien agregue la funcion recorrerPerorden el cual recorre l arbol partiendo desde la raiz, luego se va hacia el sub-arbol izquierdo, y luego hacia el sub-arbol derecho. Nuevamente se utliza recursion para recorrer el arbol. --- src/decisionTree.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/decisionTree.cpp b/src/decisionTree.cpp index e7e3eca..cb99f18 100644 --- a/src/decisionTree.cpp +++ b/src/decisionTree.cpp @@ -22,6 +22,17 @@ bool DecisionTree::buscar(const std::string& decision) const { return buscar(raiz, decision); } +void DecisionTree::recorrerPreorden() const { + recorrerPreorden(raiz); +} + +bool DecisionTree::estaVacio() const { + if(!raiz) return true; + + return false; +} + + // Metodos privados void DecisionTree::insertar(Nodo*& nodo, const std::string& decision) { // nodo va a ser la raiz del arbol @@ -98,3 +109,10 @@ bool DecisionTree::buscar(Nodo* nodo, const std::string& decision) const { } +void DecisionTree::recorrerPreorden(Nodo* nodo) const { + if(!nodo) return; + + std::cout<decision<<" "; + recorrerPreorden(nodo->izquierda); + recorrerPreorden(nodo->derecha); +} \ No newline at end of file From 1565749cb80baf0395799f21b599d17b520e4c48 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Sun, 1 Jun 2025 01:57:30 -0300 Subject: [PATCH 07/10] =?UTF-8?q?Se=20cre=C3=B3=20una=20clase=20que=20repr?= =?UTF-8?q?esenta=20la=20estructura=20=C3=A1rbol=20AVL,=20esta=20clase=20s?= =?UTF-8?q?ervir=C3=A1=20para=20realizar=20la=20gesti=C3=B3n=20de=20los=20?= =?UTF-8?q?puestos=20de=20avanzada=20en=20el=20mundo=20postapocal=C3=ADpti?= =?UTF-8?q?co=20del=20Refugio=2033.=20Los=20nodos=20del=20=C3=A1rbol=20AVL?= =?UTF-8?q?=20cuentan=20con=20caracter=C3=ADsticas=20de=20los=20puestos=20?= =?UTF-8?q?de=20avanzada=20como=20un=20identificaor=20=C3=BAnico=20y=20un?= =?UTF-8?q?=20nivel=20de=20prioridad.=20Adem=C3=A1s=20de=20los=20punteros?= =?UTF-8?q?=20a=20sus=20sub=20nodos=20izquierdo=20y=20derecho.=20Se=20creo?= =?UTF-8?q?=20el=20constructor=20de=20la=20clase,=20y=20el=20m=C3=A9todo?= =?UTF-8?q?=20insertar.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/avltree.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/avltree.cpp diff --git a/src/avltree.cpp b/src/avltree.cpp new file mode 100644 index 0000000..4544088 --- /dev/null +++ b/src/avltree.cpp @@ -0,0 +1,143 @@ +#include "avltree.hpp" + +// Constructor y destructor +AVLTree::AVLTree() { + raiz = nullptr; +} + +// Para implementar el destructor primero se debe implementar un metodo que elimine Nodos del Arbol AVL + + +// Métodos públicos +void AVLTree::insert(int& outpostId) { + // Llamamos al método privado, se le pasa la raiz. + raiz = insert(raiz, outpostId); +} + + +// Métodos privados +Nodo* AVLTree::insert(Nodo*& nodo, int& outpostId) { + // Este if se ejecutará en el caso de que sea el primer nodo a insertar (raiz == null), o en algún llamado de recursión + // cuando se llega a la posición de un nodo hijo que sea null y que en el se pueda insertar el nuevo nodo. + if(!nodo) { + return new Nodo(outpostId); + } + + // Sino, se evalúa el valor del ID para insertarlo en el sub-arbol izq. o der. + if(outpostId < nodo->outpostId) { + // Si es menor, se agrega a la izquierda, en este caso, el parámetro nodo es el puntero al nodo izquierdo de la raíz + nodo->izq = insert(nodo->izq, outpostId); + } else if(outpostId > nodo->outpostId) { + // Si es mayor, se agrega a la derecha, en este caso, el parámetro nodo es el puntero al nodo der. de la raíz + nodo->der = insert(nodo->der, outpostId); + } else { + // Sino es ni mayor ni meno quiere decir que es igual, pero no puede haber identificadores + // repetidos, entonces no se agrega. Se retorna el mismo valor de nodo que vino por parametro, dando a entender + // que si era la raiz, esta permanece igual, o si era un nodo padre de algun sub arbol, el nodo padre tampoco + // cambiara + return nodo; + } + + // Una vez agregado un nuevo nodo al arbol AVL se debe calcular la nueva altura de este, y si esta fuera del + // rango [-1, 1] se debe balancear el arbol... + // La altura en este arbol es representada por la priority + actualizarAltura(nodo); + + // Ahora verificaremos si se encuentra en el rango [-1, 1], y si está fuera se debe balancear + + int balanceDelNodo = balance(nodo); + + // Desbalanceo Left-Left: Hay un desbalance hacia la izquierda "doble". + if (balanceDelNodo > 1 && outpostId < nodo->izq->outpostId) { + // Retorna la nueva raiz que queda al hacer la rotacion + return rotarDerecha(nodo); + } + + // Desbalanceo Right-Right: Hay un desbalance hacia la derecha "doble". + if(balanceDelNodo < -1 && outpostId > nodo->der->outpostId) { + return rotarIzquierda(nodo); + } + + // Desbalanceo Left-Right: La raiz esta desbalanceada a la izquierda, y el sub arbol izq esta desbalanceado a la derecha + if(balanceDelNodo > 1 && outpostId > nodo->izq->outpostId) { + nodo->izq = rotarIzquierda(nodo->izq); + return rotarDerecha(nodo); + } + + // Desbalanceo Right-Left: La raíz está desbalanceada a la derecha, y el sub arbol der está desbalanceado a la izquierda + if(balanceDelNodo < -1 && outpostId < nodo->der->outpostId) { + nodo->der = rotarDerecha(nodo->der); + return rotarIzquierda(nodo); + } + + // Si el balance esta dentro de [-1, 1] no hay que hacer ninguna rotacion, se devuelve el nodo que llego como parametro + // que en ocasiones sera la raiz o un nodo padre en algun caso de recursion + return nodo; +} + + +// Métodos auxiliares +Nodo* AVLTree::rotarDerecha(Nodo* nodo) { + // Para razonar y comprender el metodo supongamos que el nodo es la raiz, es el caso de una raiz con un sub-arbol izquierdo + // y se agrego otro dato menor que el sub-arbol izquierdo, por ejemplo, raiz 50, sub nodo 40 y se agrego el 20 + + // El nodo que llega como parametro tiene que convertirse en el sub nodo der de su sub nodo izq + // Y el sub nodo izquierdo del nodo que llego va a ser la nueva raiz o nodo padre + + Nodo* nuevoPR = nodo->izq; // nuevoPR = nuevoPadreRaiz para indicar que es el nuevo padre o raiz + + // El sub nodo derecho, del sub nodo izquierdo del nodo que llego como parametro (es decir, el sub nodo derecho + // de la nueva raiz o nodo padre) va a ser el sub nodo izquierdo del nodo que llego, que el nodo que llego ahora es + // el sub arbol derecho de su nodo izquierdo (que ahora es el nuevo nodo padre o raiz) + Nodo* nuevoIzqDer = nuevoPR->der; // nuevoIzqDer = nuevo nodo izquierdo del nuevo nodo derecho (que es el nodo que llego como parametro) + + // A la derecha de la nueva raiz va el nodo que llego... + nuevoPR->der = nodo; + + // ... pero hay que quitarle los nodos hijos al que llego, pq sino estariamos como copiando una rama del arbol... + nodo->izq = nuevoIzqDer; // A la izquierda se quitan el 40 y 20 (en este ejemplo) y se agrega lo que estaba a la derecha + // del nuevo nodo padre o raiz + + actualizarAltura(nodo); + actualizarAltura(nuevoPR); + + return nuevoPR; + +} + +Nodo* AVLTree::rotarIzquierda(Nodo* nodo) { + Nodo* nuevoPR = nodo->der; + Nodo* nuevoDerIzq = nuevoPR->izq; + + nuevoPR->izq = nodo; + nodo->der = nuevoDerIzq; + + actualizarAltura(nodo); + actualizarAltura(nuevoPR); + + return nuevoPR; +} + +void AVLTree::actualizarAltura(Nodo* nodo) { + if(!nodo) return; + + nodo->priority = 1 + max(priority(nodo->izq), priority(nodo->der)); + + // Siempre que se agregue un nodo, este va a tener altura 1. Entonces el valor de altura que se actuliza es el de + // la raiz o algún sub-nodo si estamos en un caso de recursión. + // Por ejemplo luego de agregar un segundo elemento (ya tenemos la raíz con priority 1), la altura (o priority) de + // la raiz va a ser 1 + la altura del nodo recien agregado que tambien es 1, por lo tanto la raiz queda con una priority + // (o altura) de 2. Y el nodo recién agregado queda con altura 1. +} + +int AVLTree::priority(Nodo* nodo) { + if(!nodo) return 0; + + return nodo->priority; +} + +int AVLTree::balance(Nodo* nodo) { + if(!nodo) return 0; + + return priority(nodo->izq) - priority(nodo->der); +} From cdaf3100bc712ff656ac30ce32948b8f64546ce1 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Sun, 1 Jun 2025 21:58:03 -0300 Subject: [PATCH 08/10] =?UTF-8?q?Se=20cre=C3=B3=20un=20m=C3=A9todo=20que?= =?UTF-8?q?=20libera=20todos=20los=20nodos=20del=20arbol=20AVL=20recursiva?= =?UTF-8?q?mente,=20para=20que=20lo=20haga=20hay=20que=20pasarle=20como=20?= =?UTF-8?q?par=C3=A1metro=20el=20nodo=20ra=C3=ADz.=20Tambi=C3=A9n=20se=20i?= =?UTF-8?q?mplement=C3=B3=20el=20destructor=20de=20la=20clase,=20el=20cual?= =?UTF-8?q?=20se=20encarga=20de=20llamar=20al=20m=C3=A9todo=20que=20libera?= =?UTF-8?q?=20los=20nodos=20del=20arbol.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/avltree.hpp | 55 +++++++++++++++++++++++++++++++++++++++++++++ src/avltree.cpp | 11 +++++++++ 2 files changed, 66 insertions(+) create mode 100644 include/avltree.hpp diff --git a/include/avltree.hpp b/include/avltree.hpp new file mode 100644 index 0000000..0249116 --- /dev/null +++ b/include/avltree.hpp @@ -0,0 +1,55 @@ +#include + +/** + * El nodo representa un puesto de avanzada. Los puestos de avanzada existen en el mundo postapocaliptico del Refugio 33, y se + * encuentran distribuidos a lo largo del mapa. + * + * outpostId: Es el identificador único del puesto de avanzada. + * prority: Cada puesto de avanzada tiene una prioridad estratégica basada en diversos factores. + */ +struct Nodo { + int outpostId; + int priority; + Nodo* izq; + Nodo* der; + + Nodo(int id) : outpostId(id), priority(1), izq(nullptr), der(nullptr) {} +}; + +class AVLTree { + public: + AVLTree(); + ~AVLTree(); + + void insert(int& postId); + + private: + Nodo* raiz; // Cuando se instancia, raiz = nullptr (declarado en el constructor) + + /** + * @brief Este método se encarga de insertar un nuevo puesto de avanzada (nodo) al Arbol AVL, estructura donde + * se hace el control de los puestos de avanzada. + * + * @param nodo Para insertar un nuevo nodo al arbol se le debe pasar cual será su nodo padre. Normalmente se le pasará + * la raíz como este parámetro, aunque si se está usando en un caso de recursión nodo puedo ser algun sub-hijo. + * + * @param outpostId Es el identificador único del puesto de avanzada que se va a insertar al Arbol AVL. + * + * */ + Nodo* insert(Nodo*& nodo, int& outpostId); + void liberar(Nodo* nodo); + + // Métodos auxiliares + int max(int n1, int n2) { return n1 > n2 ? n1 : n2; } + void actualizarAltura(Nodo* nodo); + int priority(Nodo* nodo); + int balance(Nodo* nodo); + Nodo* rotarDerecha(Nodo* nodo); + Nodo* rotarIzquierda(Nodo* nodo); + + +}; + + + + diff --git a/src/avltree.cpp b/src/avltree.cpp index 4544088..6a6cf24 100644 --- a/src/avltree.cpp +++ b/src/avltree.cpp @@ -5,6 +5,10 @@ AVLTree::AVLTree() { raiz = nullptr; } +AVLTree::~AVLTree() { + liberar(raiz); +} + // Para implementar el destructor primero se debe implementar un metodo que elimine Nodos del Arbol AVL @@ -16,6 +20,13 @@ void AVLTree::insert(int& outpostId) { // Métodos privados +void AVLTree::liberar(Nodo* nodo) { + if(!nodo) return; + + liberar(nodo->izq); + liberar(nodo->der); + delete nodo; +} Nodo* AVLTree::insert(Nodo*& nodo, int& outpostId) { // Este if se ejecutará en el caso de que sea el primer nodo a insertar (raiz == null), o en algún llamado de recursión // cuando se llega a la posición de un nodo hijo que sea null y que en el se pueda insertar el nuevo nodo. From d17291019418f9b267f2cb26cfd5e1623aeff57e Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Mon, 2 Jun 2025 01:23:08 -0300 Subject: [PATCH 09/10] =?UTF-8?q?Se=20implment=C3=B3=20la=20func=C3=B3n=20?= =?UTF-8?q?bool=20contains(int=20outpostId),=20que=20funciona=20como=20enc?= =?UTF-8?q?apsulamiento=20para=20llamar=20a=20bool=20contains(Nodo*=20raiz?= =?UTF-8?q?,=20int=20outpostId)=20que=20se=20hace=20privada=20porque=20usa?= =?UTF-8?q?=20la=20ra=C3=ADz=20del=20arbol=20AVL.=20Esta=20funci=C3=B3n=20?= =?UTF-8?q?recibe=20un=20ID=20para=20buscar=20un=20puesto=20de=20avanzado?= =?UTF-8?q?=20registrado,=20si=20lo=20encuentra=20retorna=20true,=20y=20si?= =?UTF-8?q?=20no=20lo=20encuentra=20retorna=20false.=20Para=20buscar=20uti?= =?UTF-8?q?liza=20recursi=C3=B3n.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/avltree.hpp | 6 ++++-- src/avltree.cpp | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/avltree.hpp b/include/avltree.hpp index 0249116..143b20b 100644 --- a/include/avltree.hpp +++ b/include/avltree.hpp @@ -21,7 +21,8 @@ class AVLTree { AVLTree(); ~AVLTree(); - void insert(int& postId); + void insert(int outpostId); + bool contains(int outpostId); private: Nodo* raiz; // Cuando se instancia, raiz = nullptr (declarado en el constructor) @@ -36,8 +37,9 @@ class AVLTree { * @param outpostId Es el identificador único del puesto de avanzada que se va a insertar al Arbol AVL. * * */ - Nodo* insert(Nodo*& nodo, int& outpostId); + Nodo* insert(Nodo*& nodo, int outpostId); void liberar(Nodo* nodo); + bool contains(Nodo* raiz, int outpostId); // Métodos auxiliares int max(int n1, int n2) { return n1 > n2 ? n1 : n2; } diff --git a/src/avltree.cpp b/src/avltree.cpp index 6a6cf24..dd52aa5 100644 --- a/src/avltree.cpp +++ b/src/avltree.cpp @@ -13,13 +13,27 @@ AVLTree::~AVLTree() { // Métodos públicos -void AVLTree::insert(int& outpostId) { +void AVLTree::insert(int outpostId) { // Llamamos al método privado, se le pasa la raiz. raiz = insert(raiz, outpostId); } +bool AVLTree::contains(int outpostId) { + return contains(raiz, outpostId); +} + // Métodos privados +bool AVLTree::contains(Nodo* raiz, int outpostId) { + if(!raiz) return false; + + if(raiz->outpostId == outpostId) { + return true; + } + + return contains(raiz->izq, outpostId) || contains(raiz->der, outpostId); +} + void AVLTree::liberar(Nodo* nodo) { if(!nodo) return; @@ -27,7 +41,7 @@ void AVLTree::liberar(Nodo* nodo) { liberar(nodo->der); delete nodo; } -Nodo* AVLTree::insert(Nodo*& nodo, int& outpostId) { +Nodo* AVLTree::insert(Nodo*& nodo, int outpostId) { // Este if se ejecutará en el caso de que sea el primer nodo a insertar (raiz == null), o en algún llamado de recursión // cuando se llega a la posición de un nodo hijo que sea null y que en el se pueda insertar el nuevo nodo. if(!nodo) { From 57d15a3915158e4276d13692e5f6256c715cda48 Mon Sep 17 00:00:00 2001 From: benjabrezzo Date: Thu, 5 Jun 2025 20:07:26 -0300 Subject: [PATCH 10/10] =?UTF-8?q?Se=20planteo=20un=20incio=20de=20la=20fun?= =?UTF-8?q?ci=C3=B3n=20remove,=20aun=20no=20est=C3=A1=20terminada.=20Se=20?= =?UTF-8?q?hace=20este=20commit=20para=20poder=20tener=20el=20c=C3=B3digo?= =?UTF-8?q?=20actualizado=20y=20continuar=20trabajando=20en=20otra=20PC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/avltree.hpp | 2 ++ src/avltree.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/avltree.hpp b/include/avltree.hpp index 143b20b..191ecc2 100644 --- a/include/avltree.hpp +++ b/include/avltree.hpp @@ -23,6 +23,7 @@ class AVLTree { void insert(int outpostId); bool contains(int outpostId); + void remove(int outpostId); private: Nodo* raiz; // Cuando se instancia, raiz = nullptr (declarado en el constructor) @@ -40,6 +41,7 @@ class AVLTree { Nodo* insert(Nodo*& nodo, int outpostId); void liberar(Nodo* nodo); bool contains(Nodo* raiz, int outpostId); + void remove(Nodo* raiz, int outpostId); // Métodos auxiliares int max(int n1, int n2) { return n1 > n2 ? n1 : n2; } diff --git a/src/avltree.cpp b/src/avltree.cpp index dd52aa5..4c9ba33 100644 --- a/src/avltree.cpp +++ b/src/avltree.cpp @@ -22,8 +22,30 @@ bool AVLTree::contains(int outpostId) { return contains(raiz, outpostId); } +void AVLTree::remove(int outpostId) { + if(!contains(raiz, outpostId)) { + std::cout << "El puesto de avanzada con id " << outpostId << " no se encuetra registrado." << std::endl; + } else { + remove(raiz, outpostId); + } +} + // Métodos privados +void AVLTree::remove(Nodo* raiz, int outpostId) { + // El chequeo de si la raiz es null ya se hace en contains, por lo tanto no se vendrá a este método sin verificar que el + // puesto de avanzada existen en el arbol. + + if(raiz->outpostId < outpostId) { + remove(raiz->izq, outpostId); + } else if(raiz->outpostId > outpostId) { + remove(raiz->der, outpostId); + } else { + // El sucesor, o nueva raíz o padre, será el más chico del sub arbol derecho + + + } +} bool AVLTree::contains(Nodo* raiz, int outpostId) { if(!raiz) return false;