Exemplo n.º 1
0
        private void EliminarLlavedeSubarbo(BNode <TLlave, T> parentNode, TLlave keyToDelete, int subtreeIndexInNode)
        {
            BNode <TLlave, T> childNode = fabricar.TraerNodo(int.Parse(parentNode.Hijos[subtreeIndexInNode]));

            EliminarIntern(childNode, keyToDelete);
        }
Exemplo n.º 2
0
        //private BNode<TLlave, T> DeletePredecessor(BNode<TLlave, T> node)
        //{
        //    //γθμπλεταρ
        //    if (EsHoja(node.Hijos))
        //    {
        //        string ItemToRemove = node.Datos[node.Datos.Count() - 1];
        //        node.Datos = node.Datos.Where(val => val != ItemToRemove).ToArray();
        //        node.Llaves = node.Llaves.Where(val => val != ItemToRemove).ToArray();

        //    }
        //}

        private void EliminarLlavedeSubarbol(BNode <TLlave, T> parentNode, TLlave keyToDelete, int subtreeIndexInNode)
        {
            BNode <TLlave, T> childNode = fabricar.TraerNodo(int.Parse(parentNode.Hijos[subtreeIndexInNode]));

            if ((childNode.Datos.Count() > 0))
            {
                int leftIndex  = subtreeIndexInNode - 1;
                int rightIndex = subtreeIndexInNode + 1;

                BNode <TLlave, T> leftSibling = subtreeIndexInNode > 0 ?
                                                fabricar.TraerNodo(int.Parse(parentNode.Hijos[leftIndex])) : null;
                BNode <TLlave, T> rightSibling = subtreeIndexInNode < parentNode.Hijos.Count() - 1 ?
                                                 fabricar.TraerNodo(int.Parse(parentNode.Hijos[rightIndex])) : null;

                if (leftSibling != null && leftSibling.Datos.Count() > fabricar.ObtenerGrado() - 1)
                {
                    //βετα
                    List <string> lst = childNode.Datos.OfType <string>().ToList();
                    lst.Insert(0, parentNode.Datos[subtreeIndexInNode]);
                    childNode.Datos = lst;

                    lst = childNode.Llaves.OfType <string>().ToList();
                    lst.Insert(0, parentNode.Llaves[subtreeIndexInNode]);
                    childNode.Llaves = lst;

                    parentNode.Datos[subtreeIndexInNode] = leftSibling.Datos.Last();

                    string KeyToRemove  = leftSibling.Llaves[leftSibling.Datos.Count() - 1];
                    string ItemToRemove = leftSibling.Datos[leftSibling.Datos.Count() - 1];
                    leftSibling.Datos  = leftSibling.Datos.Where(val => val != ItemToRemove).ToArray().ToList();
                    leftSibling.Llaves = leftSibling.Llaves.Where(val => val != KeyToRemove).ToArray().ToList();

                    if (!EsHoja(leftSibling.Hijos))
                    {
                        //βετα
                        lst = childNode.Hijos.OfType <string>().ToList();
                        lst.Insert(0, leftSibling.Hijos.Last());
                        childNode.Hijos = lst;

                        KeyToRemove       = leftSibling.Hijos[leftSibling.Hijos.Count() - 1];
                        leftSibling.Hijos = leftSibling.Hijos.Where(val => val != KeyToRemove).ToArray().ToList();
                    }
                    fabricar.GuardarNodo(leftSibling.Informacion());
                    fabricar.GuardarNodo(parentNode.Informacion());
                    fabricar.GuardarNodo(childNode.Informacion());
                }
                else if (rightSibling != null && rightSibling.Datos.Count() > fabricar.ObtenerGrado() - 1)
                {
                    //βετα
                    childNode.Hijos[childNode.Hijos.Count() - 1] = (parentNode.Hijos[subtreeIndexInNode]);
                    parentNode.Datos[subtreeIndexInNode]         = rightSibling.Datos.First();
                    parentNode.Llaves[subtreeIndexInNode]        = rightSibling.Llaves.First();

                    string ItemToRemove = rightSibling.Datos[0];
                    rightSibling.Datos = rightSibling.Datos.Where(val => val != ItemToRemove).ToArray().ToList();

                    ItemToRemove        = rightSibling.Llaves[0];
                    rightSibling.Llaves = rightSibling.Llaves.Where(val => val != ItemToRemove).ToArray().ToList();

                    if (!EsHoja(rightSibling.Hijos))
                    {
                        List <string> lst = childNode.Hijos.OfType <string>().ToList();
                        lst.Insert(0, rightSibling.Hijos.Last());
                        childNode.Hijos = lst;

                        ItemToRemove       = rightSibling.Hijos[0];
                        rightSibling.Hijos = rightSibling.Hijos.Where(val => val != ItemToRemove).ToArray().ToList();
                    }
                    fabricar.GuardarNodo(rightSibling.Informacion());
                    fabricar.GuardarNodo(parentNode.Informacion());
                    fabricar.GuardarNodo(childNode.Informacion());
                }
                else
                {
                    //βετα
                    if (leftSibling != null)
                    {
                        List <string> lst = childNode.Datos.OfType <string>().ToList();
                        lst.Insert(0, parentNode.Datos[subtreeIndexInNode]);
                        childNode.Datos = lst;

                        lst = childNode.Llaves.OfType <string>().ToList();
                        lst.Insert(0, parentNode.Llaves[subtreeIndexInNode]);
                        childNode.Llaves = lst;

                        var oldEntries    = childNode.Datos;
                        var oldEntriesKey = childNode.Llaves;
                        childNode.Datos  = leftSibling.Datos;
                        childNode.Llaves = leftSibling.Llaves;

                        var a = new string[oldEntries.Count + childNode.Datos.Count];
                        childNode.Datos.CopyTo(a, 0);
                        oldEntries.CopyTo(a, childNode.Datos.Count);

                        a = new string[oldEntriesKey.Count + childNode.Llaves.Count];
                        childNode.Llaves.CopyTo(a, 0);
                        oldEntriesKey.CopyTo(a, childNode.Llaves.Count);

                        if (!EsHoja(leftSibling.Hijos))
                        {
                            //βετα
                            var oldChildren = childNode.Hijos;
                            childNode.Hijos = leftSibling.Hijos;

                            a = new string[oldEntries.Count + childNode.Datos.Count];
                            childNode.Datos.CopyTo(a, 0);
                            oldEntries.CopyTo(a, childNode.Datos.Count);

                            a = new string[oldEntriesKey.Count + childNode.Llaves.Count];
                            childNode.Llaves.CopyTo(a, 0);
                            oldEntriesKey.CopyTo(a, childNode.Llaves.Count);
                        }

                        string ItemToRemove = parentNode.Hijos[leftIndex];
                        parentNode.Hijos = parentNode.Hijos.Where(val => val != ItemToRemove).ToArray().ToList();

                        ItemToRemove     = parentNode.Datos[subtreeIndexInNode];
                        parentNode.Datos = parentNode.Datos.Where(val => val != ItemToRemove).ToArray().ToList();

                        ItemToRemove      = parentNode.Llaves[subtreeIndexInNode];
                        parentNode.Llaves = parentNode.Llaves.Where(val => val != ItemToRemove).ToArray().ToList();
                        fabricar.GuardarNodo(parentNode.Informacion());
                        fabricar.GuardarNodo(childNode.Informacion());
                    }
                    else if (rightSibling != null)
                    {
                        //βετα
                        childNode.Datos[childNode.Datos.Count() - 1]   = (parentNode.Datos[subtreeIndexInNode]);
                        childNode.Llaves[childNode.Llaves.Count() - 1] = (parentNode.Llaves[subtreeIndexInNode]);
                        if (rightSibling != null)
                        {
                            var a = new string[rightSibling.Datos.Count + childNode.Datos.Count];
                            childNode.Datos.CopyTo(a, 0);
                            rightSibling.Datos.CopyTo(a, childNode.Datos.Count);

                            a = new string[rightSibling.Llaves.Count + childNode.Llaves.Count];
                            childNode.Llaves.CopyTo(a, 0);
                            rightSibling.Llaves.CopyTo(a, childNode.Llaves.Count);

                            if (!EsHoja(rightSibling.Hijos))
                            {
                                a = new string[rightSibling.Hijos.Count + childNode.Hijos.Count];
                                childNode.Hijos.CopyTo(a, 0);
                                rightSibling.Hijos.CopyTo(a, childNode.Hijos.Count);
                            }

                            string ItemToRemove = parentNode.Hijos[rightIndex];
                            parentNode.Hijos = parentNode.Hijos.Where(val => val != ItemToRemove).ToArray().ToList();

                            ItemToRemove     = parentNode.Datos[subtreeIndexInNode];
                            parentNode.Datos = parentNode.Datos.Where(val => val != ItemToRemove).ToArray().ToList();

                            ItemToRemove      = parentNode.Llaves[subtreeIndexInNode];
                            parentNode.Llaves = parentNode.Llaves.Where(val => val != ItemToRemove).ToArray().ToList();

                            fabricar.GuardarNodo(parentNode.Informacion());
                            fabricar.GuardarNodo(childNode.Informacion());
                        }
                    }
                }
            }
            EliminarInterno(childNode, keyToDelete);
        }
Exemplo n.º 3
0
 public BTree(string FileName, int Grado)
 {
     fabricar = new Fabrica <TLlave, T>(FileName, Grado);
     root     = null;
     grado    = Grado;
 }
Exemplo n.º 4
0
 public BTree(string FileName)
 {
     fabricar = new Fabrica <TLlave, T>(FileName);
     root     = fabricar.TraerNodo(fabricar.ObtenerRaiz());
     grado    = fabricar.ObtenerGrado();
 }
Exemplo n.º 5
0
        private void InsertarEnNodoLleno(BNode <TLlave, T> nodo, TLlave key, T dato)
        {
            string            llave = key.ToString();
            string            info  = dato.ToString();
            BNode <TLlave, T> Padre;
            BNode <TLlave, T> Nuevo;
            BNode <TLlave, T> hijo1 = null;
            BNode <TLlave, T> hijo2 = null;
            int i, j;

            bool salir = false;

            do
            {
                if (nodo == null)
                {
                    int posicion = fabricar.ObtenerPosicionLibre();
                    fabricar.NodoDeFabrica();
                    fabricar.CambiarRaiz(posicion);
                    nodo = fabricar.TraerNodo(posicion);
                    root = nodo;

                    //Cambiar altura
                    int altura = fabricar.ObtenerAltura();
                    altura++;
                    fabricar.CambiarAltura(altura);
                }

                Padre = fabricar.TraerNodo(nodo.Padre);

                if (!HayEspacio(nodo.Llaves))
                {
                    //Overflow

                    List <string> lista      = new List <string>();
                    List <string> listaDatos = new List <string>();
                    List <string> listapunt  = new List <string>();

                    //Se crea el nodo Derecho
                    int libre = fabricar.ObtenerPosicionLibre();
                    fabricar.NodoDeFabrica();
                    Nuevo = fabricar.TraerNodo(libre);

                    //Se crean listas para encontrar el nodo que debe subir
                    i = 0;

                    while ((llave.CompareTo(nodo.Llaves[i]) > 0) && (i < grado - 1))
                    {
                        lista.Insert(i, nodo.Llaves[i]);
                        listaDatos.Insert(i, nodo.Datos[i]);
                        listapunt.Insert(i, nodo.Hijos[i]);
                        i++;

                        if (i == nodo.Llaves.Count())
                        {
                            break;
                        }
                    }

                    lista.Insert(i, llave);
                    listaDatos.Insert(i, info);

                    if (hijo1 != null)
                    {
                        listapunt.Insert(i, hijo1.Posicion.ToString("D11"));
                    }
                    else
                    {
                        listapunt.Insert(i, int.MinValue.ToString());
                    }

                    if (hijo2 != null)
                    {
                        listapunt.Insert(i + 1, hijo2.Posicion.ToString("D11"));
                    }
                    else
                    {
                        listapunt.Insert(i + 1, int.MinValue.ToString());
                    }


                    while (i < grado - 1)
                    {
                        lista.Insert(i + 1, nodo.Llaves[i]);
                        listaDatos.Insert(i + 1, nodo.Datos[i]);
                        listapunt.Insert(i + 2, nodo.Hijos[i + 1]);
                        i++;
                    }


                    //Se reconoce cual es el centro del nodo.

                    int centro = 0;

                    if ((lista.Count % 2) == 0)
                    {
                        //Grado Par
                        centro = (lista.Count / 2) - 1;
                    }
                    else
                    {
                        //Grado Impar
                        centro = lista.Count / 2;
                    }


                    //Dividir los nodos

                    //Nodo Izquierdo

                    for (j = 0; j < nodo.Llaves.Count; j++)
                    {
                        if (j < centro)
                        {
                            nodo.Llaves[j] = lista[j];
                            nodo.Datos[j]  = listaDatos[j];
                            nodo.Hijos[j]  = listapunt[j];
                        }
                        else
                        {
                            nodo.Llaves[j] = llaveNull;
                            nodo.Datos[j]  = llaveNull;
                            nodo.Hijos[j]  = int.MinValue.ToString();
                        }
                    }


                    //Para limpiar los demas nodos :s
                    nodo.Hijos[centro] = listapunt[centro];

                    if (centro != nodo.Hijos.Count)
                    {
                        for (int x = centro + 1; x < nodo.Hijos.Count; x++)
                        {
                            nodo.Hijos[x] = int.MinValue.ToString();
                        }
                    }

                    //Nodo Derecho

                    for (j = 0; j < Nuevo.Llaves.Count; j++)
                    {
                        if (grado % 2 == 0)
                        {
                            if (j <= centro)
                            {
                                Nuevo.Llaves[j] = lista[centro + j + 1];
                                Nuevo.Datos[j]  = listaDatos[centro + j + 1];
                                Nuevo.Hijos[j]  = listapunt[centro + j + 1];
                            }
                        }
                        else
                        {
                            if (j < centro)
                            {
                                Nuevo.Llaves[j] = lista[centro + j + 1];
                                Nuevo.Datos[j]  = listaDatos[centro + j + 1];
                                Nuevo.Hijos[j]  = listapunt[centro + j + 1];
                            }
                        }
                    }

                    Nuevo.Hijos[EspaciosUsados(Nuevo.Llaves)] = listapunt[grado];

                    //Hay que corregir los hijos en cada nodo creado

                    for (j = 0; j <= EspaciosUsados(nodo.Llaves); j++)
                    {
                        BNode <TLlave, T> temp = fabricar.TraerNodo(int.Parse(nodo.Hijos[j]));

                        if (temp != null)
                        {
                            temp.Padre = nodo.Posicion;
                            fabricar.GuardarNodo(temp.Informacion());
                        }
                    }
                    //if (nodo->Hijos[j])
                    //    (nodo->Hijos[j])->Padre = nodo;

                    for (j = 0; j <= EspaciosUsados(Nuevo.Llaves); j++)
                    {
                        BNode <TLlave, T> temp = fabricar.TraerNodo(int.Parse(Nuevo.Hijos[j]));
                        if (temp != null)
                        {
                            temp.Padre = Nuevo.Posicion;
                            fabricar.GuardarNodo(temp.Informacion());
                        }
                    }

                    llave = lista[centro];
                    info  = listaDatos[centro];
                    hijo1 = nodo;
                    hijo2 = Nuevo;
                    fabricar.GuardarNodo(hijo1.Informacion());
                    fabricar.GuardarNodo(hijo2.Informacion());
                    nodo = Padre;
                }
                else
                {
                    //Continua insertando
                    //Inserta la clave en su lugar

                    i = 0;

                    if (EspaciosUsados(nodo.Llaves) > 0)
                    {
                        int llavesUsadas = EspaciosUsados(nodo.Llaves);

                        while ((i < llavesUsadas) && (llave.CompareTo(nodo.Llaves[i]) > 0))
                        {
                            i++;
                        }
                        {
                            for (j = llavesUsadas; j > i; j--)
                            {
                                nodo.Llaves[j] = nodo.Llaves[j - 1];
                                nodo.Datos[j]  = nodo.Datos[j - 1];
                            }

                            for (j = llavesUsadas + 1; j > i; j--)
                            {
                                nodo.Hijos[j] = nodo.Hijos[j - 1];
                            }
                        }
                    }

                    nodo.Llaves[i] = llave;
                    nodo.Datos[i]  = info;

                    //Asignar hijo 1 al nodo
                    if (hijo1 != null)
                    {
                        nodo.Hijos[i] = int.Parse(hijo1.Posicion.ToString()).ToString("D11");
                        hijo1.Padre   = nodo.Posicion;
                    }
                    else
                    {
                        nodo.Hijos[i] = int.MinValue.ToString();
                    }

                    //Asignar hijo 2 al nodo
                    if (hijo2 != null)
                    {
                        nodo.Hijos[i + 1] = int.Parse(hijo2.Posicion.ToString()).ToString("D11");
                        hijo2.Padre       = nodo.Posicion;
                    }
                    else
                    {
                        nodo.Hijos[i + 1] = int.MinValue.ToString();
                    }

                    //Guardamos los datos
                    fabricar.GuardarNodo(nodo.Informacion());
                    fabricar.GuardarNodo(hijo1.Informacion());
                    fabricar.GuardarNodo(hijo2.Informacion());

                    salir = true;
                }
            }while (!salir);
        }