private void RecorrerPostOrdenRecursivo(int posicionActual, StringBuilder texto) { if (posicionActual == Utilidades.ApuntadorVacio) { return; } NodoB <T> nodoActual = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, posicionActual, _fabrica); for (int i = 0; i < nodoActual.Hijos.Count; i++) { RecorrerPreOrdenRecursivo(nodoActual.Hijos[i], texto); } EscribirNodo(nodoActual, texto); }
private void RecorrerInOrdenRecursivo(int posicionActual, StringBuilder texto) { if (posicionActual == Utilidades.ApuntadorVacio) { return; } NodoB <T> nodoActual = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, posicionActual, _fabrica); for (int i = 0; i < nodoActual.Hijos.Count; i++) { RecorrerInOrdenRecursivo(nodoActual.Hijos[i], texto); if ((i < nodoActual.Llaves.Count) && (nodoActual.Llaves[i] != "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")) { miListado.Add(nodoActual.Datos[i].ToString()); texto.AppendLine(nodoActual.Llaves[i].ToString()); texto.AppendLine(nodoActual.Datos[i].ToString()); texto.AppendLine("---------------"); } } }
private void AgregarRecursivo(int posicionNodoActual, string llave, T dato) { NodoB <T> nodoActual = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, posicionNodoActual, _fabrica); if (nodoActual.PosicionExactaEnNodo(llave) != -1) { throw new InvalidOperationException("La llave indicada ya está contenida en el árbol."); } if (nodoActual.EsHoja) { // Se debe insertar en este nodo, por lo que se hace la llamada // al método encargado de insertar y ajustar el árbol si es necesario Subir(nodoActual, llave, dato, Utilidades.ApuntadorVacio); GuardarEncabezado(); } else { // Se hace una llamada recursiva, bajando en el subarbol // correspondiente según la posición aproximada de la llave AgregarRecursivo(nodoActual.Hijos[nodoActual.PosicionAproximadaEnNodo(llave)], llave, dato); } }
private NodoB <T> ObtenerRecursivo(int posicionNodoActual, string llave, out int posicion) { NodoB <T> nodoActual = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, posicionNodoActual, _fabrica); posicion = nodoActual.PosicionExactaEnNodo(llave); if (posicion != -1) { return(nodoActual); } else { if (nodoActual.EsHoja) { return(null); } else { int posicionAproximada = nodoActual.PosicionAproximadaEnNodo(llave); return(ObtenerRecursivo(nodoActual.Hijos[posicionAproximada], llave, out posicion)); } } }
private void Subir(NodoB <T> nodoActual, string llave, T dato, int hijoDerecho) { // Si el nodo no está lleno, se agrega la información // al nodo y el método termina if (!nodoActual.Lleno) { nodoActual.AgregarDato(llave, dato, hijoDerecho); nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); return; } // Creo un nuevo nodo hermano NodoB <T> nuevoHermano = new NodoB <T>(Orden, _ultimaPosicionLibre, nodoActual.Padre, _fabrica); _ultimaPosicionLibre++; // Datos a subir al padre luego de la separación string llavePorSubir = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"; T datoPorSubir = _fabrica.FabricarNulo(); // Se llama al método que hace la separación nodoActual.SepararNodo(llave, dato, hijoDerecho, nuevoHermano, ref llavePorSubir, ref datoPorSubir); // Actualizar el apuntador en todos los hijos NodoB <T> nodoHijo = null; for (int i = 0; i < nuevoHermano.Hijos.Count; i++) { if (nuevoHermano.Hijos[i] != Utilidades.ApuntadorVacio) { // Se carga el hijo para modificar su apuntador al padre nodoHijo = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, nuevoHermano.Hijos[i], _fabrica); nodoHijo.Padre = nuevoHermano.Posicion; nodoHijo.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); } else { break; } } // Evaluo el caso del Padre if (nodoActual.Padre == Utilidades.ApuntadorVacio) // Es la raiz { // Creo un nuevo nodo Raiz NodoB <T> nuevaRaiz = new NodoB <T>(Orden, _ultimaPosicionLibre, Utilidades.ApuntadorVacio, _fabrica); _ultimaPosicionLibre++; Altura++; // Agrego la información nuevaRaiz.Hijos[0] = nodoActual.Posicion; nuevaRaiz.AgregarDato(llavePorSubir, datoPorSubir, nuevoHermano.Posicion); // Actualizo los apuntadores al padre nodoActual.Padre = nuevaRaiz.Posicion; nuevoHermano.Padre = nuevaRaiz.Posicion; _raiz = nuevaRaiz.Posicion; // Guardo los cambios nuevaRaiz.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nuevoHermano.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); } else // No es la raiz { nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nuevoHermano.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); // Cargar el nodo Padre NodoB <T> nodoPadre = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, nodoActual.Padre, _fabrica); Subir(nodoPadre, llavePorSubir, datoPorSubir, nuevoHermano.Posicion); } }