Esempio n. 1
0
        /*
         *
         *      Función recursiva para eliminar una Clave en el árbol, empezamos con el caso base de que sea una hoja, en caso de que no checamos las condiciones buscando si tenemos raiz.
         *      En este método checamos los nodos vecinos de la hoja y vemos si alguno puede realizar algún prestamo, en caso de que no sea posible
         *
         */
        public bool EliminaEnArbol(Arbol arbol, Nodo nodo, int clave, long direccion, string Ruta, Atributo A, string RutaDicc)
        {
            int  DatosMinimos = (Arbol.GradoArbol - 1) / 2;
            char tipo         = nodo.TipoNodo;

            if (tipo == 'H')
            {
                if (!nodo.EliminaDatoEnHoja(clave))
                {
                    return(false);
                }
            }
            else
            {
                if (!nodo.EliminaEnNodoRaiz(clave, direccion))
                {
                    return(false);
                }
            }
            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
            if (tipo != 'R')
            {
                if (nodo.ObtenNumeroLlavesValidas() < DatosMinimos)
                {
                    Nodo VecinoD   = arbol.ObtenNodoVecinoDer(nodo);
                    Nodo VecinoI   = arbol.ObtenNodoVecinoIzq(nodo);
                    Nodo NodoPadre = arbol.ObtenNodoPadre(nodo);
                    if (VecinoD != null && arbol.ChecaSiTienenElMismoPadre(nodo, VecinoD) && VecinoD.ObtenNumeroLlavesValidas() - 1 >= DatosMinimos)
                    {
                        if (tipo == 'H')
                        {
                            long DirPrestada = VecinoD.DireccionLlaves[0];
                            int  CvePrestada = VecinoD.Llaves[0];

                            if (!VecinoD.EliminaDatoEnHoja(CvePrestada))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(VecinoD, archivo, Ruta);

                            nodo.InsertaOrdenadoEnHoja(CvePrestada, DirPrestada);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);

                            int IndiceActualizarPadre = NodoPadre.DireccionLlaves.IndexOf(nodo.DirNodo);
                            NodoPadre.Llaves[IndiceActualizarPadre] = VecinoD.Llaves[0];
                            ManejadorArchivo.EscribeNodo(NodoPadre, archivo, Ruta);
                        }
                        else
                        {
                            long DirVecino      = VecinoD.DireccionLlaves[0];
                            int  CveVecino      = VecinoD.Llaves[0];
                            int  IndiceCvePadre = NodoPadre.DireccionLlaves.IndexOf(nodo.DirNodo);
                            int  CveNodoPadre   = NodoPadre.Llaves[IndiceCvePadre];

                            if (!VecinoD.EliminaEnNodoRaiz(CveVecino, DirVecino))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(VecinoD, archivo, Ruta);

                            NodoPadre.Llaves[IndiceCvePadre] = CveVecino;
                            ManejadorArchivo.EscribeNodo(NodoPadre, archivo, Ruta);

                            nodo.InsertaOrdenadoEnRaiz(CveNodoPadre, DirVecino);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                        }
                    }
                    else if (VecinoI != null && arbol.ChecaSiTienenElMismoPadre(nodo, VecinoI) && VecinoI.ObtenNumeroLlavesValidas() - 1 >= DatosMinimos)
                    {
                        if (tipo == 'H')
                        {
                            int  CvePrestada = VecinoI.Llaves[VecinoI.ObtenNumeroLlavesValidas() - 1];
                            long DirPrestada = VecinoI.DireccionLlaves[VecinoI.ObtenNumeroLlavesValidas() - 1];

                            if (!VecinoI.EliminaDatoEnHoja(CvePrestada))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(VecinoI, archivo, Ruta);
                            nodo.InsertaOrdenadoEnHoja(CvePrestada, DirPrestada);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);

                            int IndiceActualizarPadre = NodoPadre.DireccionLlaves.IndexOf(VecinoI.DirNodo);
                            NodoPadre.Llaves[IndiceActualizarPadre] = CvePrestada;
                            ManejadorArchivo.EscribeNodo(NodoPadre, archivo, Ruta);
                        }
                        else
                        {
                            long DirVecino      = VecinoI.DireccionLlaves[VecinoI.ObtenNumeroLlavesValidas()];
                            int  CveVecino      = VecinoI.Llaves[VecinoI.ObtenNumeroLlavesValidas() - 1];
                            int  IndiceCvePadre = NodoPadre.DireccionLlaves.IndexOf(VecinoI.DirNodo);
                            int  CveNodoPadre   = NodoPadre.Llaves[IndiceCvePadre];

                            if (!VecinoI.EliminaEnNodoRaiz(CveVecino, DirVecino))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(VecinoI, archivo, Ruta);

                            NodoPadre.Llaves[IndiceCvePadre] = CveVecino;
                            ManejadorArchivo.EscribeNodo(NodoPadre, archivo, Ruta);

                            nodo.InsertaOrdenadoEnRaiz(CveNodoPadre, DirVecino);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                        }
                    }
                    else if (VecinoD != null && arbol.ChecaSiTienenElMismoPadre(nodo, VecinoD))
                    {
                        if (tipo == 'H')
                        {
                            for (int i = 0; i < VecinoD.ObtenNumeroLlavesValidas(); i++)
                            {
                                nodo.InsertaOrdenadoEnHoja(VecinoD.Llaves[i], VecinoD.DireccionLlaves[i]);
                            }
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                            if (NodoPadre.TipoNodo == 'R' && NodoPadre.ObtenNumeroLlavesValidas() == 1)
                            {
                                A.Direccion_Indice = VecinoD.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                int  idx_eliminar_NodoPadre = NodoPadre.DireccionLlaves.IndexOf(VecinoD.DirNodo);
                                int  NuevaCve = NodoPadre.Llaves[idx_eliminar_NodoPadre - 1];
                                long NuevaDir = NodoPadre.DireccionLlaves[idx_eliminar_NodoPadre];

                                return(EliminaEnArbol(arbol, NodoPadre, NuevaCve, NuevaDir, Ruta, A, RutaDicc));
                            }
                        }
                        else
                        {
                            int  CveNodoPadre = NodoPadre.Llaves[NodoPadre.DireccionLlaves.IndexOf(nodo.DirNodo)];
                            long Dir0Vecino   = VecinoD.DireccionLlaves[0];

                            VecinoD.InsertaOrdenadoEnRaiz(CveNodoPadre, Dir0Vecino);

                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                VecinoD.InsertaOrdenadoEnRaiz(nodo.Llaves[i], nodo.DireccionLlaves[i + 1]);
                            }
                            VecinoD.DireccionLlaves[0] = nodo.DireccionLlaves[0];

                            if (NodoPadre.TipoNodo == 'R' && NodoPadre.ObtenNumeroLlavesValidas() == 1)
                            {
                                VecinoD.TipoNodo = 'R';
                                ManejadorArchivo.EscribeNodo(VecinoD, archivo, Ruta);
                                A.Direccion_Indice = VecinoD.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                ManejadorArchivo.EscribeNodo(VecinoD, archivo, Ruta);
                                return(EliminaEnArbol(arbol, NodoPadre, CveNodoPadre, nodo.DirNodo, Ruta, A, RutaDicc));
                            }
                        }
                    }
                    else if (VecinoI != null && arbol.ChecaSiTienenElMismoPadre(nodo, VecinoI))
                    {
                        if (tipo == 'H')
                        {
                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                VecinoI.InsertaOrdenadoEnHoja(nodo.Llaves[i], nodo.DireccionLlaves[i]);
                            }
                            ManejadorArchivo.EscribeNodo(VecinoI, archivo, Ruta);
                            if (NodoPadre.TipoNodo == 'R' && NodoPadre.ObtenNumeroLlavesValidas() == 1)
                            {
                                VecinoI.TipoNodo   = 'R';
                                A.Direccion_Indice = VecinoI.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                int  idx_eliminar_NodoPadre = NodoPadre.DireccionLlaves.IndexOf(nodo.DirNodo);
                                int  NuevaCve = NodoPadre.Llaves[idx_eliminar_NodoPadre - 1];
                                long NuevaDir = NodoPadre.DireccionLlaves[idx_eliminar_NodoPadre];

                                return(EliminaEnArbol(arbol, NodoPadre, NuevaCve, NuevaDir, Ruta, A, RutaDicc));
                            }
                        }
                        else
                        {
                            int  CveNodoPadre = NodoPadre.Llaves[NodoPadre.DireccionLlaves.IndexOf(VecinoI.DirNodo)];
                            long Dir0NodoHijo = nodo.DireccionLlaves[0];

                            VecinoI.InsertaOrdenadoEnRaiz(CveNodoPadre, Dir0NodoHijo);

                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                VecinoI.InsertaOrdenadoEnRaiz(nodo.Llaves[i], nodo.DireccionLlaves[i + 1]);
                            }

                            if (NodoPadre.TipoNodo == 'R' && NodoPadre.ObtenNumeroLlavesValidas() == 1)
                            {
                                VecinoI.TipoNodo = 'R';
                                ManejadorArchivo.EscribeNodo(VecinoI, archivo, Ruta);
                                A.Direccion_Indice = VecinoI.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                ManejadorArchivo.EscribeNodo(VecinoI, archivo, Ruta);
                                return(EliminaEnArbol(arbol, NodoPadre, CveNodoPadre, nodo.DirNodo, Ruta, A, RutaDicc));
                            }
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        public bool EliminaEnArbol(Arbol arbol, Nodo nodo, int clave, long direccion, string Ruta, Atributo A, string RutaDicc)
        {
            int  DatosMinimos = (Arbol.GradoArbol - 1) / 2;
            char tipo         = nodo.TipoNodo;

            if (tipo == 'H')
            {
                if (!nodo.EliminaDatoEnHoja(clave))
                {
                    return(false);
                }
            }
            else
            {
                if (!nodo.EliminaEnNodoRaiz(clave, direccion))
                {
                    return(false);
                }
            }
            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
            if (tipo != 'R')
            {
                if (nodo.ObtenNumeroLlavesValidas() < DatosMinimos)
                {
                    Nodo padre      = arbol.ObtenNodoPadre(nodo);
                    Nodo vecino_der = arbol.ObtenNodoVecinoDer(nodo);
                    Nodo vecino_izq = arbol.ObtenNodoVecinoIzq(nodo);

                    if (vecino_der != null && arbol.ChecaSiTienenElMismoPadre(nodo, vecino_der) && vecino_der.ObtenNumeroLlavesValidas() - 1 >= DatosMinimos)
                    {
                        if (tipo == 'H')
                        {
                            long prestado_dir = vecino_der.DireccionLlaves[0];
                            int  prestado_cve = vecino_der.Llaves[0];

                            if (!vecino_der.EliminaDatoEnHoja(prestado_cve))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(vecino_der, archivo, Ruta);

                            nodo.InsertaOrdenadoEnHoja(prestado_cve, prestado_dir);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);

                            int idx_actualizar_padre = padre.DireccionLlaves.IndexOf(nodo.DirNodo);
                            padre.Llaves[idx_actualizar_padre] = vecino_der.Llaves[0];
                            ManejadorArchivo.EscribeNodo(padre, archivo, Ruta);
                        }
                        else
                        {
                            long vecino_dir    = vecino_der.DireccionLlaves[0];
                            int  vecino_cve    = vecino_der.Llaves[0];
                            int  idx_cve_padre = padre.DireccionLlaves.IndexOf(nodo.DirNodo);
                            int  padre_cve     = padre.Llaves[idx_cve_padre];

                            if (!vecino_der.EliminaEnNodoRaiz(vecino_cve, vecino_dir))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(vecino_der, archivo, Ruta);

                            padre.Llaves[idx_cve_padre] = vecino_cve;
                            ManejadorArchivo.EscribeNodo(padre, archivo, Ruta);

                            nodo.InsertaOrdenadoEnRaiz(padre_cve, vecino_dir);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                        }
                    }
                    else if (vecino_izq != null && arbol.ChecaSiTienenElMismoPadre(nodo, vecino_izq) && vecino_izq.ObtenNumeroLlavesValidas() - 1 >= DatosMinimos)
                    {
                        if (tipo == 'H')
                        {
                            long prestado_dir = vecino_izq.DireccionLlaves[vecino_izq.ObtenNumeroLlavesValidas() - 1];
                            int  prestado_cve = vecino_izq.Llaves[vecino_izq.ObtenNumeroLlavesValidas() - 1];

                            if (!vecino_izq.EliminaDatoEnHoja(prestado_cve))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(vecino_izq, archivo, Ruta);

                            nodo.InsertaOrdenadoEnHoja(prestado_cve, prestado_dir);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);

                            int idx_actualizar_padre = padre.DireccionLlaves.IndexOf(vecino_izq.DirNodo);
                            padre.Llaves[idx_actualizar_padre] = prestado_cve;
                            ManejadorArchivo.EscribeNodo(padre, archivo, Ruta);
                        }
                        else
                        {
                            long vecino_dir    = vecino_izq.DireccionLlaves[vecino_izq.ObtenNumeroLlavesValidas()];
                            int  vecino_cve    = vecino_izq.Llaves[vecino_izq.ObtenNumeroLlavesValidas() - 1];
                            int  idx_cve_padre = padre.DireccionLlaves.IndexOf(vecino_izq.DirNodo);
                            int  padre_cve     = padre.Llaves[idx_cve_padre];

                            if (!vecino_izq.EliminaEnNodoRaiz(vecino_cve, vecino_dir))
                            {
                                return(false);
                            }
                            ManejadorArchivo.EscribeNodo(vecino_izq, archivo, Ruta);

                            padre.Llaves[idx_cve_padre] = vecino_cve;
                            ManejadorArchivo.EscribeNodo(padre, archivo, Ruta);

                            nodo.InsertaOrdenadoEnRaiz(padre_cve, vecino_dir);
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                        }
                    }
                    else if (vecino_der != null && arbol.ChecaSiTienenElMismoPadre(nodo, vecino_der))
                    {
                        if (tipo == 'H')
                        {
                            for (int i = 0; i < vecino_der.ObtenNumeroLlavesValidas(); i++)
                            {
                                nodo.InsertaOrdenadoEnHoja(vecino_der.Llaves[i], vecino_der.DireccionLlaves[i]);
                            }
                            ManejadorArchivo.EscribeNodo(nodo, archivo, Ruta);
                            if (padre.TipoNodo == 'R' && padre.ObtenNumeroLlavesValidas() == 1)
                            {
                                A.Direccion_Indice = vecino_der.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                int  idx_eliminar_padre = padre.DireccionLlaves.IndexOf(vecino_der.DirNodo);
                                int  dato_nuevo         = padre.Llaves[idx_eliminar_padre - 1];
                                long dir_nueva          = padre.DireccionLlaves[idx_eliminar_padre];

                                return(EliminaEnArbol(arbol, padre, dato_nuevo, dir_nueva, Ruta, A, RutaDicc));
                            }
                        }
                        else
                        {
                            int  cve_padre   = padre.Llaves[padre.DireccionLlaves.IndexOf(nodo.DirNodo)];
                            long dir0_vecino = vecino_der.DireccionLlaves[0];

                            vecino_der.InsertaOrdenadoEnRaiz(cve_padre, dir0_vecino);

                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                vecino_der.InsertaOrdenadoEnRaiz(nodo.Llaves[i], nodo.DireccionLlaves[i + 1]);
                            }
                            vecino_der.DireccionLlaves[0] = nodo.DireccionLlaves[0];

                            if (padre.TipoNodo == 'R' && padre.ObtenNumeroLlavesValidas() == 1)
                            {
                                vecino_der.TipoNodo = 'R';
                                ManejadorArchivo.EscribeNodo(vecino_der, archivo, Ruta);
                                A.Direccion_Indice = vecino_der.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                ManejadorArchivo.EscribeNodo(vecino_der, archivo, Ruta);
                                return(EliminaEnArbol(arbol, padre, cve_padre, nodo.DirNodo, Ruta, A, RutaDicc));
                            }
                        }
                    }
                    else if (vecino_izq != null && arbol.ChecaSiTienenElMismoPadre(nodo, vecino_izq))
                    {
                        if (tipo == 'H')
                        {
                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                vecino_izq.InsertaOrdenadoEnHoja(nodo.Llaves[i], nodo.DireccionLlaves[i]);
                            }
                            ManejadorArchivo.EscribeNodo(vecino_izq, archivo, Ruta);
                            if (padre.TipoNodo == 'R' && padre.ObtenNumeroLlavesValidas() == 1)
                            {
                                vecino_izq.TipoNodo = 'R';
                                A.Direccion_Indice  = vecino_izq.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                int  idx_eliminar_padre = padre.DireccionLlaves.IndexOf(nodo.DirNodo);
                                int  dato_nuevo         = padre.Llaves[idx_eliminar_padre - 1];
                                long dir_nueva          = padre.DireccionLlaves[idx_eliminar_padre];

                                return(EliminaEnArbol(arbol, padre, dato_nuevo, dir_nueva, Ruta, A, RutaDicc));
                            }
                        }
                        else
                        {
                            int  cve_padre = padre.Llaves[padre.DireccionLlaves.IndexOf(vecino_izq.DirNodo)];
                            long dir0_nodo = nodo.DireccionLlaves[0];

                            vecino_izq.InsertaOrdenadoEnRaiz(cve_padre, dir0_nodo);

                            for (int i = 0; i < nodo.ObtenNumeroLlavesValidas(); i++)
                            {
                                vecino_izq.InsertaOrdenadoEnRaiz(nodo.Llaves[i], nodo.DireccionLlaves[i + 1]);
                            }

                            if (padre.TipoNodo == 'R' && padre.ObtenNumeroLlavesValidas() == 1)
                            {
                                vecino_izq.TipoNodo = 'R';
                                ManejadorArchivo.EscribeNodo(vecino_izq, archivo, Ruta);
                                A.Direccion_Indice = vecino_izq.DirNodo;
                                ManejadorArchivo.ModificaAtributo(A, RutaDicc, archivo);
                            }
                            else
                            {
                                ManejadorArchivo.EscribeNodo(vecino_izq, archivo, Ruta);
                                return(EliminaEnArbol(arbol, padre, cve_padre, nodo.DirNodo, Ruta, A, RutaDicc));
                            }
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }