void RecursiveInOrder(List <T> TargetList, int actualNode) { string Line = FindNode(actualNode); if (actualNode != 0) { DiskBNode <T> actual = new DiskBNode <T>(delegate_toT, ValueLength, Degree); actual.ToTObj(Line); Stack <int> aux = new Stack <int>(); if (actual.HasSons()) { while (actual.BNodeSons.Count != 0) { aux.Push(actual.BNodeSons.Peek()); RecursiveInOrder(TargetList, actual.BNodeSons.Pop()); T Value = actual.BNodeValues.GetByIndex(aux.Count - 1); if (Value != null) { TargetList.Add(Value); actual.BNodeValues.Enlist(Value); } } } else { while (!actual.BNodeValues.IsEmpty()) { TargetList.Add(actual.BNodeValues.Get()); } } } }
T RecursiveFindMinor(int son_id) { DiskBNode <T> Actual = new DiskBNode <T>(delegate_toT, ValueLength, Degree); string Line = FindNode(son_id); Actual.ToTObj(Line); if (Actual.HasSons()) { return(RecursiveFindMinor(Actual.BNodeSons.Peek())); } else { T ToReturn = Actual.BNodeValues.Get(); Actual.Insert(ToReturn); RecursiveDelete(ToReturn.Key, Actual.ID, false); return(ToReturn); } }
T FindMinor(int _sonID, ref bool underflow, bool RightSon) { DiskBNode <T> Actual = new DiskBNode <T>(delegate_toT, ValueLength, Degree); string Line = FindNode(_sonID); Actual.ToTObj(Line); if (Actual.HasSons()) { return(RecursiveFindMinor(Actual.BNodeSons.Peek())); } else { if (Actual.BNodeValues.GetLength() > Math.Round((Degree / 2.00) - 1)) { underflow = false; if (RightSon) { T ToReturn = Actual.BNodeValues.Get(); RewriteNode(Actual.ID, Actual.ToFixedLengthText()); return(ToReturn); } else { T ToReturn = Actual.BNodeValues.GetHead(); RewriteNode(Actual.ID, Actual.ToFixedLengthText()); return(ToReturn); } } else { underflow = true; return(default(T)); } } }
T ValueRotation(ref bool success, ref bool rightBrother) { DiskBNode <T> Parent = new DiskBNode <T>(delegate_toT, ValueLength, Degree); DiskBNode <T> Brother = new DiskBNode <T>(delegate_toT, ValueLength, Degree); string Line = FindNode(ParentID); Parent.ToTObj(Line); T ReturnValue; Stack <int> temp = new Stack <int>(); //volver a llenar BNodeSons do { temp.Push(Parent.BNodeSons.Pop()); } while (temp.Peek() != ActualID); int ParentValueIndex = temp.Count - 1; if (Parent.BNodeSons.Count != 0 && Parent.BNodeSons.Peek() != 0) { Line = FindNode(Parent.BNodeSons.Peek()); Brother.ToTObj(Line); if (Brother.BNodeValues.GetLength() > Math.Round((Degree / 2.00) - 1)) { rightBrother = true; ReturnValue = Parent.BNodeValues.GetByIndex(ParentValueIndex); Parent.BNodeValues.Enlist(Brother.BNodeValues.Get()); success = true; int count = temp.Count; for (int i = 0; i < count; i++) { Parent.BNodeSons.Push(temp.Pop()); } if (Brother.HasSons()) { GreatestSons.Push(Brother.BNodeSons.Pop()); } RewriteNode(Parent.ID, Parent.ToFixedLengthText()); RewriteNode(Brother.ID, Brother.ToFixedLengthText()); return(ReturnValue); } else { Parent.BNodeSons.Push(temp.Pop()); if (temp.Count != 0 && temp.Peek() != 0) { Line = FindNode(temp.Peek()); while (!Brother.BNodeValues.IsEmpty()) { Brother.BNodeValues.Get(); } int count = Brother.BNodeSons.Count; for (int i = 0; i < count; i++) { Brother.BNodeSons.Pop(); } Brother.ToTObj(Line); if (Brother.BNodeValues.GetLength() > Math.Round((Degree / 2.00) - 1)) { rightBrother = false; ReturnValue = Parent.BNodeValues.GetByIndex(ParentValueIndex - 1); Parent.BNodeValues.Enlist(Brother.BNodeValues.GetHead()); success = true; count = temp.Count; for (int i = 0; i < count; i++) { Parent.BNodeSons.Push(temp.Pop()); } count = Brother.BNodeSons.Count; for (int i = 0; i < count; i++) { if (Brother.BNodeSons.Peek() == 0) { Brother.BNodeSons.Pop(); } else { temp.Push(Brother.BNodeSons.Pop()); } } if (temp.Count != 0) { GreatestSons.Push(temp.Pop()); } count = temp.Count; for (int i = 0; i < count; i++) { Brother.BNodeSons.Push(temp.Pop()); } RewriteNode(Parent.ID, Parent.ToFixedLengthText()); RewriteNode(Brother.ID, Brother.ToFixedLengthText()); return(ReturnValue); } else { count = temp.Count; for (int i = 0; i < count; i++) { Parent.BNodeSons.Push(temp.Pop()); } //Unión con padre y hermano derecho success = false; return(default(T)); } } else { //Unión con padre y hermano derecho success = false; return(default(T)); } } } else { Parent.BNodeSons.Push(temp.Pop()); Line = FindNode(temp.Peek()); while (!Brother.BNodeValues.IsEmpty()) { Brother.BNodeValues.Get(); } int count = Brother.BNodeSons.Count; for (int i = 0; i < count; i++) { Brother.BNodeSons.Pop(); } Brother.ToTObj(Line); if (Brother.BNodeValues.GetLength() > Math.Round((Degree / 2.00) - 1)) { rightBrother = false; ReturnValue = Parent.BNodeValues.GetByIndex(ParentValueIndex - 1); Parent.BNodeValues.Enlist(Brother.BNodeValues.GetHead()); success = true; count = temp.Count; for (int i = 0; i < count; i++) { Parent.BNodeSons.Push(temp.Pop()); } count = Brother.BNodeSons.Count; for (int i = 0; i < count; i++) { if (Brother.BNodeSons.Peek() == 0) { Brother.BNodeSons.Pop(); } else { temp.Push(Brother.BNodeSons.Pop()); } } if (temp.Count != 0) { GreatestSons.Push(temp.Pop()); } count = temp.Count; for (int i = 0; i < count; i++) { Brother.BNodeSons.Push(temp.Pop()); } RewriteNode(Parent.ID, Parent.ToFixedLengthText()); RewriteNode(Brother.ID, Brother.ToFixedLengthText()); return(ReturnValue); } else { //Unión con padre y hermano izquierdo count = temp.Count; for (int i = 0; i < count; i++) { Parent.BNodeSons.Push(temp.Pop()); } success = false; return(default(T)); } } }
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); } }
bool RecursiveInsert(int ID, T _newValue) { DiskBNode <T> Actual = new DiskBNode <T>(delegate_toT, ValueLength, Degree); string Line = FindNode(ID); Actual.ToTObj(Line); if (!Actual.HasSons()) { bool isFull = Actual.BNodeValues.IsFull(); bool inserted = Actual.Insert(_newValue); if (inserted) { if (isFull) { for (int i = 0; i < Degree / 2; i++) { //vaciar GreatestValues GreatestValues.Push(Actual.BNodeValues.GetHead()); } MiddleValue = Actual.BNodeValues.GetHead(); if (Actual.Parent == 0) { Actual.Parent = AvailableID + 1; } ParentID = Actual.Parent; ActualID = Actual.ID; RewriteNode(ActualID, Actual.ToFixedLengthText()); DivideNode(); return(true); } else { RewriteNode(ID, Actual.ToFixedLengthText()); return(true); } } else { return(false); } } else { int SonIndex = Actual.BNodeValues.GetSonIndex(_newValue); int SonID = -1; Stack <int> AuxStack = new Stack <int>(); for (int i = 0; i <= SonIndex; i++) { SonID = Actual.BNodeSons.Peek(); AuxStack.Push(Actual.BNodeSons.Pop()); } int count = AuxStack.Count; for (int j = 0; j < count; j++) { Actual.BNodeSons.Push(AuxStack.Pop()); } if (SonID != -1) { return(RecursiveInsert(SonID, _newValue)); } else { return(false); } } }