示例#1
0
 public ArbolB(int orden, string nombreArchivo, IFabricaTextoTamañoFijo <T> fabrica)
 {
     // Se guardan los parámetros recibidos
     _archivoNombre = nombreArchivo;
     _fabrica       = fabrica;
     // Se abre la conexión al archivo
     _archivo = new FileStream(_archivoNombre, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
     // Se obtienen los valores del encabezado del archivo
     _raiz = Utilidades.LeerEntero(_archivo, 0);
     _ultimaPosicionLibre = Utilidades.LeerEntero(_archivo, 1);
     Tamaño = Utilidades.LeerEntero(_archivo, 2);
     Orden  = Utilidades.LeerEntero(_archivo, 3);
     Altura = Utilidades.LeerEntero(_archivo, 4);
     // Se corrigen los valores del encabezado cuando el archivos no existe previamente
     if (_ultimaPosicionLibre == Utilidades.ApuntadorVacio)
     {
         _ultimaPosicionLibre = 0;
     }
     if (Tamaño == Utilidades.ApuntadorVacio)
     {
         Tamaño = 0;
     }
     if (Orden == Utilidades.ApuntadorVacio)
     {
         Orden = orden;
     }
     if (Altura == Utilidades.ApuntadorVacio)
     {
         Altura = 1;
     }
     if (_raiz == Utilidades.ApuntadorVacio)
     {
         // Se crea la cabeza del árbol vacía
         // para evitar futurs errores
         NodoB <T> nodoCabeza = new NodoB <T>(Orden, _ultimaPosicionLibre, Utilidades.ApuntadorVacio, _fabrica);
         _ultimaPosicionLibre++;
         _raiz = nodoCabeza.Posicion;
         nodoCabeza.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario);
     }
     // Si el archivo existe solamente se actualizan los encabezados, sino
     // se crea y luego se almacenan los valores iniciales
     GuardarEncabezado();
 }
示例#2
0
        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 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
            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);
            }
        }