// Call this after the default constructor was invoked. private bool Initialize(byte bySlotLen) { if (bySlotLen < 2) { throw new ArgumentOutOfRangeException("bySlotLen", "Slot Length needs to be >= 2"); } if (bySlotLen % 2 != 0) { if (bySlotLen == byte.MaxValue) { bySlotLen--; } else { bySlotLen++; } } #if (!DEBUG && TRIALWARE) const string ExpireMsg = "BTreeGold trial period has expired.\nVisit 4A site(http://www.4atech.net) to get details in getting a license."; if (!System.IO.File.Exists("Trialware.dll") || Trialware.ExpirationManager.Instance == null || Trialware.ExpirationManager.Instance.IsExpired()) { throw new InvalidOperationException(ExpireMsg); } #endif this.SlotLength = bySlotLen; Root = new TreeRootNode(this); SetCurrentItemAddress(Root, 0); _tempSlots = new BTreeItem <TKey, TValue> [SlotLength + 1]; _tempChildren = new TreeNode[SlotLength + 2]; return(true); // successful }
/// <summary> /// Remove "Item" from the tree. Doesn't throw exception if "Item" is not found /// </summary> /// <param name="key"> </param> public bool Remove(TKey key) // return true if found, else false { if (Count > 0) { var item = new BTreeItem <TKey, TValue>(key, default(TValue)); if (CurrentEntry == null) { if (Root.Search(this, item, false)) { Remove(); return(true); } } else if (Comparer.Compare(CurrentEntry.Key, key) == 0) { Remove(); return(true); } else { if (Root.Search(this, item, false)) { Remove(); return(true); } } } return(false); }
/// <summary> /// Delete the current item from the tree. Tree is maintained to be balanced and sorted. /// </summary> internal protected void Remove() { BTreeItem <TKey, TValue> Temp = null; if (CurrentItem.Node != null) { Temp = CurrentItem.Node.Slots[CurrentItem.NodeItemIndex]; } if (Temp != null) { CurrentItem.Node.Remove(this); do { FixVacatedSlot = false; CurrentItem.Node.FixTheVacatedSlot(this); } while (FixVacatedSlot); // Make the current item pointer point to null since we just deleted the current item. There is no efficient way to point the current item // pointer to point to the next or previous item. In BPlus this is possible but since this is not BPLus.. SetCurrentItemAddress(null, 0); Root.Count--; Temp = null; TreeNode.ResetArray(TempSlots, null); TempParent = null; } }
// Needed for cloning (shallow copy) this BTree. private void Initialize(BTreeAlgorithm <TKey, TValue> BTree) { this.SlotLength = BTree.SlotLength; this.Root = BTree.Root; //Copy CurrentItem. "Copy" as CurrentItem is value type. this.CurrentItem = BTree.CurrentItem; this.Comparer = BTree.Comparer; // create another set of temporary slots for thread safe 'Search' operation support TempSlots = new BTreeItem <TKey, TValue> [SlotLength + 1]; TempChildren = new TreeNode[SlotLength + 2]; }
// Needed for cloning (shallow copy) this BTree. private void Initialize(BTreeAlgorithm <TKey, TValue> bTree) { this.SlotLength = bTree.SlotLength; this.Comparer = bTree.Comparer; this.Root = new TreeRootNode(this); //this.Root = bTree.Root; //Copy CurrentItem. "Copy" as CurrentItem is value type. this.CurrentItem = bTree.CurrentItem; // create another set of temporary slots for thread safe 'Search' operation support _tempSlots = new BTreeItem <TKey, TValue> [SlotLength + 1]; _tempChildren = new TreeNode[SlotLength + 2]; // copy the tree graph. bTree.Locker.Invoke(() => { Copy(bTree); }); }
/// <summary> /// Search btree for a certain record (Item). If current record is equal /// to Item then true will be returned without doing any search operation. /// This minimizes unnecessary BTree traversal. If Item is found, it becomes the current item. /// </summary> /// <param name="Item">record to search for</param> /// <param name="GoToFirstInstance">if true, will make first instance of duplicated keys the current record</param> /// <returns>Returns true if found else, false</returns> public bool Search(TKey Key, bool GoToFirstInstance) { if (Count > 0) { if (CurrentEntry == null || Comparer.Compare(CurrentEntry.Key, Key) != 0 || GoToFirstInstance) { BTreeItem <TKey, TValue> Item = new BTreeItem <TKey, TValue>(Key, default(TValue)); bool r = Root.Search(this, Item, GoToFirstInstance); TreeNode.ResetArray(TempSlots, null); TempParent = null; return(r); } return(true); // current entry is equal to ObjectToSearch!! } // tree is empty return(false); }
/// <summary> /// Search btree for a certain record (Item). If current record is equal /// to Item then true will be returned without doing any search operation. /// This minimizes unnecessary BTree traversal. If Item is found, it becomes the current item. /// </summary> /// <param name="key"> </param> /// <param name="goToFirstInstance">if true, will make first instance of duplicated keys the current record</param> /// <returns>Returns true if found else, false</returns> public bool Search(TKey key, bool goToFirstInstance) { if (Count > 0) { var o = CurrentEntry; if (o == null || Comparer.Compare(o.Key, key) != 0 || goToFirstInstance) { var item = new BTreeItem <TKey, TValue>(key, default(TValue)); bool r = Root.Search(this, item, goToFirstInstance); //TreeNode.ResetArray(_tempSlots, null); _tempParent = null; return(r); } return(true); // current entry is equal to ObjectToSearch!! } // tree is empty return(false); }
/// <summary> /// Delete the current item from the tree. Tree is maintained to be balanced and sorted. /// </summary> protected internal void Remove() { BTreeItem <TKey, TValue> temp = null; if (CurrentItem.Node != null) { temp = CurrentItem.Node.Slots[CurrentItem.NodeItemIndex]; } if (temp == null) { return; } CurrentItem.Node.Remove(this); ProcessFixAndPull(); // Make the current item pointer point to null since we just deleted the current item. There is no efficient way to point the current item // pointer to point to the next or previous item. In BPlus this is possible but since this is not BPLus.. SetCurrentItemAddress(null, 0); Root.TreeCount--; TreeNode.ResetArray(_tempSlots, null); _tempParent = null; }
public int Compare(BTreeItem <TKey, TValue> x, BTreeItem <TKey, TValue> y) { return(KeyComparer.Compare(x.Key, y.Key)); }
static void Main(string[] args) { var fileLines = string.Empty; var assembly = typeof(Program).GetTypeInfo().Assembly; var pathToFile = GetResourcePath(assembly); using (var stream = assembly.GetManifestResourceStream(pathToFile)) using (var reader = new StreamReader(stream)) { fileLines = reader.ReadToEnd(); } var bTreeItems = new List <BTreeItem>(); var delimeters = new string[] { "\r\n", "\n", "\r" }; var treeData = fileLines.Split(delimeters, StringSplitOptions.RemoveEmptyEntries); foreach (var line in treeData) { var delimeterindex = line.IndexOf(':'); var bindex = Convert.ToInt32(string.Join("", line.Take(delimeterindex))); var values = line.Substring(delimeterindex, line.Length - delimeterindex) .TrimStart(':') .TrimStart(' ') .TrimEnd(' ') .Split(' ') .Select(item => Convert.ToInt32(item)) .ToArray(); var itemB = new BTreeItem { Index = bindex, Values = values }; bTreeItems.Add(itemB); } // Создание дерева var BT = new BTree <int, int>(5); Console.WriteLine("Ввод значений дерева. Сколько элементов загрузить? (От 10 до 15)"); var N = Convert.ToInt32(Console.ReadLine()); var bTreeSize = bTreeItems.Sum(item => item.Values.Length); Console.WriteLine($"{(N <= bTreeSize ? "Размер верный" : "Ошибка размера")}"); if (N <= bTreeSize) { for (int i = 0; i < bTreeItems.Count; i++) { var item = bTreeItems[i]; var values = item.Values; for (int j = 0; j < values.Length; j++) { var value = values[j]; BT.Insert(value, item.Index); } } PrintTree(BT, "Начальное дерево: "); Console.WriteLine("Введите элемент для добавления"); var forInsert = Convert.ToInt32(Console.ReadLine()); BT.Insert(forInsert, 1); PrintTree(BT, "Начальное дерево: "); Console.WriteLine("Введите элемент для добавления"); forInsert = Convert.ToInt32(Console.ReadLine()); BT.Insert(forInsert, 1); PrintTree(BT, "Начальное дерево: "); Console.WriteLine("Введите элемент для удаления"); var forDel = Convert.ToInt32(Console.ReadLine()); BT.Delete(forDel); PrintTree(BT, $"\nДерево после удаления {forDel} элемента: "); } }