/* * * 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); }