public BNode <TKey, T> ConvertirLinea(string nombreArchivo, int posi, int grado) { if (posi <= -2147483648) { return(null); } fileStream = new FileStream(nombreArchivo + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite); // Posición para escribir PosicionLinea = EncabezadoTamaño + (posi - 1) * (34 + (11 * grado + (grado - 1)) + (36 * (grado - 1) + (grado - 2)) + (36 * (grado - 1) + (grado - 1))); // Posición para leer fileStream.Seek(PosicionLinea, SeekOrigin.Begin); // Lectura StreamReader leer = new StreamReader(fileStream); // De linea a nodo string linea = leer.ReadLine(); string[] ArrayLinea = linea.Split('|'); leer.Close(); // Posición int nodoPosi = int.Parse(ArrayLinea[0]); int nodoPadre = int.Parse(ArrayLinea[1]); int arrayHijos = 4; int arrayLlaves = arrayHijos + grado + 2; int arrayDatos = arrayLlaves + (grado - 1) + 2; // Se incluyen los diferentes atributos int apendice = arrayDatos + grado - 1; // Llenado de los hijos List <int> hijo = new List <int>(); for (int i = arrayHijos; i < arrayLlaves - 2; i++) { hijo.Add(int.Parse(ArrayLinea[i])); } hijo.Add(-2147483648); // Llenado de las llaves List <TKey> llave = new List <TKey>(); for (int i = arrayLlaves; i < arrayDatos - 2; i++) { if (ArrayLinea[i].Contains("#")) { llave.Add((TKey)(object)null); } else { llave.Add((TKey)(object)ArrayLinea[i]); } } // Espacio temporal (↓f) llave.Add((TKey)(object)null); // Llenado de los datos List <T> dato = new List <T>(); for (int i = arrayDatos; i < apendice; i++) { if (ArrayLinea[i].Contains("#")) { dato.Add((T)(object)null); } else { dato.Add((T)(object)ArrayLinea[i]); } } // Espacio temporal (↓f) dato.Add((T)(object)null); // Creacion del Nodo ARBOL B BNode <TKey, T> nodoNuevo = new BNode <TKey, T>(dato, hijo, llave, nodoPadre, nodoPosi, grado); return(nodoNuevo); }
private BNode <TKey, T> CrearMezcla(int corriente, int hermanoNodo, int espacioPadre, BNode <TKey, T> padrel) { BNode <TKey, T> nuevoNodo; // Eliminar al padre del que ya se eliminio if (corriente < hermanoNodo) { nuevoNodo = archivoArbol.ConvertirLinea(nombreArchivo, padrel.ApuntaHijo[corriente], grado); nuevoNodo.Llave[nuevoNodo.LlaveCon()] = padrel.Llave[espacioPadre]; nuevoNodo.Datos[nuevoNodo.DatoCon()] = padrel.Datos[espacioPadre]; EliminarIndex.Enqueue(espacioPadre); EliminarPadre.Enqueue(padrel.Posi); EliminarUnder(padrel, espacioPadre); BNode <TKey, T> hermano = archivoArbol.ConvertirLinea(nombreArchivo, padrel.ApuntaHijo[hermanoNodo], grado); for (int i = 0; i < hermano.LlaveCon(); i++) { nuevoNodo.Llave[nuevoNodo.LlaveCon()] = hermano.Llave[i]; nuevoNodo.Datos[nuevoNodo.DatoCon()] = hermano.Datos[i]; } for (int j = 0; j < hermano.HijoCon(); j++) { nuevoNodo.ApuntaHijo[nuevoNodo.HijoCon()] = hermano.ApuntaHijo[j]; } BNode <TKey, T> padre = archivoArbol.ConvertirLinea(nombreArchivo, hermano.Padre, grado); padre.ApuntaHijo.Remove(hermano.Posi); padre.ApuntaHijo[padre.HijoCon()] = nuevoNodo.Posi; archivoArbol.InsertarNodo(padre, nombreArchivo, true); hermano.Padre = -2147483648; archivoArbol.InsertarNodo(hermano, nombreArchivo, true); } else { nuevoNodo = archivoArbol.ConvertirLinea(nombreArchivo, padrel.ApuntaHijo[hermanoNodo], grado); nuevoNodo.Llave[nuevoNodo.LlaveCon()] = (padrel.Llave[espacioPadre]); nuevoNodo.Datos[nuevoNodo.LlaveCon()] = (padrel.Datos[espacioPadre]); EliminarIndex.Enqueue(espacioPadre); EliminarPadre.Enqueue(padrel.Posi); EliminarUnder(padrel, espacioPadre); BNode <TKey, T> corrient = archivoArbol.ConvertirLinea(nombreArchivo, padrel.ApuntaHijo[corriente], grado); for (int i = 0; i < corrient.LlaveCon(); i++) { nuevoNodo.Llave[nuevoNodo.LlaveCon()] = corrient.Llave[i]; nuevoNodo.Datos[nuevoNodo.LlaveCon()] = corrient.Datos[i]; } for (int j = 0; j < corrient.HijoCon(); j++) { nuevoNodo.ApuntaHijo[nuevoNodo.HijoCon()] = corrient.ApuntaHijo[j]; } BNode <TKey, T> padrelo = archivoArbol.ConvertirLinea(nombreArchivo, corrient.Padre, grado); padrelo.ApuntaHijo.Remove(corrient.Posi); padrelo.ApuntaHijo[padrelo.HijoCon()] = nuevoNodo.Posi; archivoArbol.InsertarNodo(padrelo, nombreArchivo, true); corrient.Padre = -2147483648; archivoArbol.InsertarNodo(corrient, nombreArchivo, true); } List <int> hijoCorrecto = new List <int>(); for (int i = 0; i < nuevoNodo.ApuntaHijo.Count; i++) { if (nuevoNodo.ApuntaHijo[i] > -2147483648) { hijoCorrecto.Add(nuevoNodo.ApuntaHijo[i]); } } nuevoNodo.ApuntaHijo = hijoCorrecto; return(nuevoNodo); }
private void UnderF(BNode <TKey, T> nuevoB) { // Se inserta inmediatamente por no ser underflow if (nuevoB.Under()) { archivoArbol.InsertarNodo(nuevoB, nombreArchivo, true); archivoArbol.ConstruccionEncabezado(nombreArchivo, archivoArbol.ObtenerRaiz(nombreArchivo), archivoArbol.UltimaPosicion(nombreArchivo), tamaño, grado, 0); return; } // Se determina quien sube if (grado % 2 == 0) { // Sube el de en medio si es impar factor = (grado / 2) - 1; } else { // Sube el de en medio +1 si es impar factor = (grado / 2); } // Se obtien la ultima posicion disponible int posicion = archivoArbol.UltimaPosicion(nombreArchivo); // Si el padre es nulo, es raiz if (nuevoB.Padre == -2147483648) { // Hijo Derecho BNode <TKey, T> derecho = new BNode <TKey, T>(); // Atributos derecho.Posi = posicion; derecho.Padre = posicion + 1; derecho.Grado = grado; for (int i = factor + 1; i <= grado; i++) { derecho.ApuntaHijo.Add(nuevoB.ApuntaHijo.ElementAt(i)); derecho.Datos.Add(nuevoB.Datos.ElementAt(i)); derecho.Llave.Add(nuevoB.Llave.ElementAt(i)); } // Actualización de los padres en el nuevo nodo for (int i = 0; i < derecho.ApuntaHijo.Count; i++) { if (derecho.ApuntaHijo.ElementAt(i) != -2147483648) { BNode <TKey, T> padresNuevos = archivoArbol.ConvertirLinea(nombreArchivo, derecho.ApuntaHijo.ElementAt(i), grado); padresNuevos.Padre = derecho.Posi; archivoArbol.InsertarNodo(padresNuevos, nombreArchivo, true); } } // Creacion de nueva raiz BNode <TKey, T> raiznueva = new BNode <TKey, T>(); // Atributos raiznueva.Posi = posicion + 1; raiznueva.Padre = -2147483648; raiznueva.Grado = grado; raiznueva.ApuntaHijo.Add(nuevoB.Posi); raiznueva.ApuntaHijo.Add(posicion); raiznueva.Datos.Add(nuevoB.Datos.ElementAt(factor)); raiznueva.Llave.Add(nuevoB.Llave.ElementAt(factor)); // Hijo Izquierdo nuevoB.Padre = posicion + 1; nuevoB.ApuntaHijo.RemoveRange(factor + 1, nuevoB.ApuntaHijo.Count - (factor + 1)); nuevoB.Datos.RemoveRange(factor, nuevoB.Datos.Count - factor); nuevoB.Llave.RemoveRange(factor, nuevoB.Llave.Count - factor); // Se realizan cambios en el archivo archivoArbol.InsertarNodo(nuevoB, nombreArchivo, true); archivoArbol.InsertarNodo(derecho, nombreArchivo, false); archivoArbol.InsertarNodo(raiznueva, nombreArchivo, false); // Actualización de encabezado archivoArbol.ConstruccionEncabezado(nombreArchivo, raiznueva.Posi, posicion + 2, tamaño, grado, 0); } else { // Llamar al padre BNode <TKey, T> padre = archivoArbol.ConvertirLinea(nombreArchivo, nuevoB.Padre, grado); for (int i = 0; i < grado; i++) { try { if (padre.Llave.ElementAt(i).CompareTo(nuevoB.Llave.ElementAt(factor)) == 1 || padre.Llave.ElementAt(i) == null) { padre.Llave.Insert(i, nuevoB.Llave.ElementAt(factor)); padre.Datos.Insert(i, nuevoB.Datos.ElementAt(factor)); padre.ApuntaHijo.Insert(i + 1, posicion); break; } } catch (NullReferenceException) { padre.Llave.Insert(i, nuevoB.Llave.ElementAt(factor)); padre.Datos.Insert(i, nuevoB.Datos.ElementAt(factor)); padre.ApuntaHijo.Insert(i + 1, posicion); break; } } // Hijo derecho BNode <TKey, T> derecho = new BNode <TKey, T>(); // Atributos derecho.Posi = posicion; derecho.Padre = posicion + 1; derecho.Grado = grado; for (int i = factor + 1; i <= grado; i++) { derecho.ApuntaHijo.Add(nuevoB.ApuntaHijo.ElementAt(i)); derecho.Datos.Add(nuevoB.Datos.ElementAt(i)); derecho.Llave.Add(nuevoB.Llave.ElementAt(i)); } // Actualización de los padres en el nuevo nodo for (int i = 0; i < derecho.ApuntaHijo.Count; i++) { if (derecho.ApuntaHijo.ElementAt(i) != -2147483648) { BNode <TKey, T> padresNuevos = archivoArbol.ConvertirLinea(nombreArchivo, derecho.ApuntaHijo.ElementAt(i), grado); padresNuevos.Padre = derecho.Posi; archivoArbol.InsertarNodo(padresNuevos, nombreArchivo, true); } } // Hijo izquierdo nuevoB.ApuntaHijo.RemoveRange(factor + 1, nuevoB.ApuntaHijo.Count - (factor + 1)); nuevoB.Datos.RemoveRange(factor, nuevoB.Datos.Count - factor); nuevoB.Llave.RemoveRange(factor, nuevoB.Llave.Count - factor); // Se realizan cambios en el archivo archivoArbol.InsertarNodo(nuevoB, nombreArchivo, true); archivoArbol.InsertarNodo(derecho, nombreArchivo, false); archivoArbol.InsertarNodo(padre, nombreArchivo, true); // Actualización de encabezado archivoArbol.ConstruccionEncabezado(nombreArchivo, archivoArbol.ObtenerRaiz(nombreArchivo), posicion + 1, tamaño, grado, 0); // Llamar recursivamente al padre UnderF(padre); } }
private void EliminarUnder(BNode <TKey, T> corrienete, int valorIndex) { corrienete.Llave.RemoveAt(valorIndex); corrienete.Datos.RemoveAt(valorIndex); archivoArbol.InsertarNodo(corrienete, nombreArchivo, true); }