Пример #1
0
        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);
        }
Пример #2
0
        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] != ""))
                {
                    texto.AppendLine(nodoActual.Llaves[i].ToString());
                    texto.AppendLine(nodoActual.Datos[i].ToString());
                    texto.AppendLine("---------------");
                }
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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));
                }
            }
        }
Пример #5
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);
            }
        }