Beispiel #1
0
        bool RecursiveDelete(IComparable ValueKey, int NodeID, bool backReview)
        {
            DiskBNode <T> Actual = new DiskBNode <T>(delegate_toT, ValueLength, Degree);
            string        Line   = FindNode(NodeID);

            Actual.ToTObj(Line);
            bool hasSons;

            if (!backReview)
            {
                hasSons = Actual.HasSons();
            }
            else
            {
                hasSons = false;
            }

            bool        isFull   = Actual.BNodeValues.IsFull();
            int         count    = Actual.BNodeValues.GetLength();
            Stack <int> AuxStack = new Stack <int>();
            int         sonID    = -1;
            bool        exit     = false;
            int         i        = 0;
            T           deletedValue;

            while (!Actual.BNodeValues.IsEmpty() && !exit)
            {
                auxiliar.Push(Actual.BNodeValues.Get());
                if (ValueKey.CompareTo(auxiliar.Peek().Key) == 0)
                {
                    //eliminar valor
                    deletedValue = auxiliar.Pop();
                    exit         = true;
                    if (hasSons)
                    {
                        //i es index del valor
                        sonID = Actual.GetSonID(i + 1);
                        //FindMinor requiere ID de hijo izquierdo
                        bool Right             = true;
                        bool Underflow         = false;
                        T    ParentReplacement = FindMinor(sonID, ref Underflow, Right);
                        if (Underflow)
                        {
                            sonID             = Actual.GetSonID(i);
                            Right             = false;
                            ParentReplacement = FindMinor(sonID, ref Underflow, Right);
                            if (Underflow)
                            {
                                ActualID = Actual.GetSonID(i);
                                ParentID = Actual.ID;


                                sonUnion(Actual.GetSonID(i + 1));
                                do
                                {
                                    AuxStack.Push(Actual.BNodeSons.Pop());
                                } while (AuxStack.Peek() != ActualID);
                                AuxStack.Pop();
                                count = AuxStack.Count;
                                for (int k = 0; k < count; k++)
                                {
                                    Actual.BNodeSons.Push(AuxStack.Pop());
                                }
                            }
                            else
                            {
                                Actual.BNodeValues.Enlist(ParentReplacement);
                            }
                        }
                        else
                        {
                            Actual.BNodeValues.Enlist(ParentReplacement);
                        }
                    }
                }
                i++;
            }
            count = auxiliar.Count;
            for (int j = 0; j < count; j++)
            {
                Actual.BNodeValues.Enlist(auxiliar.Pop());
            }

            if (exit)
            {
                if (Actual.Parent != 0)
                {
                    if (Actual.BNodeValues.GetLength() < Math.Round((Degree / 2.00) - 1))
                    {
                        bool Rotation         = false;
                        bool fromRightBrother = false;
                        ActualID = Actual.ID;
                        ParentID = Actual.Parent;
                        //Rotación de valores
                        T replacement = ValueRotation(ref Rotation, ref fromRightBrother);


                        if (Rotation)
                        {
                            Actual.Insert(replacement);
                            if (GreatestSons.Count != 0 && GreatestSons.Peek() != 0)
                            {
                                DiskBNode <T> ToAddSon = new DiskBNode <T>(delegate_toT, ValueLength, Degree);
                                Line = FindNode(GreatestSons.Peek());
                                ToAddSon.ToTObj(Line);
                                ToAddSon.Parent = Actual.ID;
                                RewriteNode(GreatestSons.Peek(), ToAddSon.ToFixedLengthText());
                                if (fromRightBrother)
                                {
                                    count = Actual.BNodeSons.Count;
                                    for (int j = 0; j < count; j++)
                                    {
                                        if (Actual.BNodeSons.Peek() == 0)
                                        {
                                            Actual.BNodeSons.Pop();
                                        }
                                        else
                                        {
                                            AuxStack.Push(Actual.BNodeSons.Pop());
                                        }
                                    }

                                    Actual.BNodeSons.Push(GreatestSons.Pop());
                                    count = AuxStack.Count;
                                    for (int k = 0; k < count; k++)
                                    {
                                        Actual.BNodeSons.Push(AuxStack.Pop());
                                    }
                                }
                                else
                                {
                                    Actual.BNodeSons.Push(GreatestSons.Pop());
                                }
                            }
                        }
                        else
                        {
                            //Unión de hermanos y padre
                            Actual.Parent = 0;
                            while (!Actual.BNodeValues.IsEmpty())
                            {
                                GreatestValues.Push(Actual.BNodeValues.GetHead());
                            }
                            count = Actual.BNodeSons.Count;
                            for (int j = 0; j < count; j++)
                            {
                                GreatestSons.Push(Actual.BNodeSons.Pop());
                            }
                            DeleteNode();
                        }
                    }
                }
                else
                {
                    if (Actual.BNodeValues.IsEmpty())
                    {
                        count = Actual.BNodeSons.Count;
                        for (int k = 0; k < count; k++)
                        {
                            Actual.BNodeSons.Pop();
                        }
                        if (backReview)
                        {
                            RewriteNode(NodeID, Actual.ToFixedLengthText());
                            UpdateHeader();
                            return(false);
                        }
                    }
                }
                RewriteNode(NodeID, Actual.ToFixedLengthText());

                return(true);
            }
            else if (hasSons)
            {
                int SonIndex = Actual.BNodeValues.GetSonIndex(ValueKey);
                sonID = -1;

                for (int h = 0; h <= SonIndex; h++)
                {
                    sonID = Actual.BNodeSons.Peek();
                    AuxStack.Push(Actual.BNodeSons.Pop());
                }
                count = AuxStack.Count;
                for (int j = 0; j < count; j++)
                {
                    Actual.BNodeSons.Push(AuxStack.Pop());
                }
                if (sonID != -1)
                {
                    return(RecursiveDelete(ValueKey, sonID, false));
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }