public void ActualizaNodoPadre(Nodo Padre, int Clave, long Direccion, Arbol a, string Ruta, string RutaArchDicc, Atributo A) { if (Padre.InsertaOrdenadoEnRaiz(Clave, Direccion)) // En caso de que el padre todavía tenga espacio { ManejadorArchivo.EscribeNodo(Padre, archivo, Ruta); } else { char TipoNodo = Padre.TipoNodo; if (TipoNodo == 'R') // El padre se vuelve intermedio { Padre.TipoNodo = 'I'; } List <int> AuxInt = new List <int>(); foreach (int i in Padre.Llaves) { AuxInt.Add(i); } AuxInt.Add(Clave); // Se inserta la primera clave del nuevo nodo AuxInt.Sort(); int IndiceDivisorio = (Arbol.GradoArbol - 1) / 2; int ClaveASubir = AuxInt[IndiceDivisorio]; List <Nodo> Intermedios = DivideRaiz(Clave, Direccion, AuxInt, Padre, Ruta); ManejadorArchivo.EscribeNodo(Intermedios[0], archivo, Ruta); ManejadorArchivo.EscribeNodo(Intermedios[1], archivo, Ruta); if (TipoNodo == 'R') // En caso de que el nodo que se dividió era raiz { Nodo NuevaRaiz = CreaNodo('R', ManejadorArchivo.ObtenUltimaDireccion(Ruta, archivo)); NuevaRaiz.DireccionLlaves[0] = Intermedios[0].DirNodo; NuevaRaiz.DireccionLlaves[1] = Intermedios[1].DirNodo; NuevaRaiz.Llaves[0] = ClaveASubir; A.Direccion_Indice = NuevaRaiz.DirNodo; ManejadorArchivo.ModificaAtributo(A, RutaArchDicc, archivo); ManejadorArchivo.EscribeNodo(NuevaRaiz, archivo, Ruta); } else { Nodo PadreTemp = a.ObtenNodoPadre(Intermedios[0]); ActualizaNodoPadre(PadreTemp, ClaveASubir, Intermedios[1].DirNodo, new Arbol(ManejadorArchivo.ObtenNodos(A, archivo, Ruta), A), Ruta, RutaArchDicc, A); } } }
/* * * 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); }