// вырезание узла private HeapNode <TPriority, TItem> MoveToRoot(HeapNode <TPriority, TItem> node) { // запомнить родителя HeapNode <TPriority, TItem> parent = node.Parent; // удалить родителя, добавить в корневой список, снять пометку node.RemoveParent(); Trees.AddFirst(node); node.Marked = false; return(parent); }
/// <summary> /// Cuts the given node from its parent and moves it to the list of root trees. Returns the parent of the node, prior to it /// being cut /// </summary> private HeapNode <TPriority, TItem> MoveToRoot(HeapNode <TPriority, TItem> node) { // Remeber ref to parent because child is about to be cut HeapNode <TPriority, TItem> parent = node.Parent; // Remove ref to parent and parent ref to child node.RemoveParent(); Trees.AddFirst(node); node.Marked = false; // Return old parent of node return(parent); }
// доваить элемент в кучу public HeapNode <TPriority, TItem> Insert(TPriority priority, TItem value) { // добавить дерево с данным элементов HeapNode <TPriority, TItem> node = new HeapNode <TPriority, TItem>(priority, value); Trees.AddFirst(node); //обновить минимум. // Элемент минимум если он единственный в куче или его приритет меньше приоритета min if (Count == 0 || node.Priority.CompareTo(Minimum.Priority) < 0) { minimumTreesNode = Trees.First; } Count++; return(node); }
/// <summary> /// Inserts the given item into the heap maintaining the heap order property. O(1) operation /// </summary> /// <param name="priority">The priority of the item</param> /// <param name="value">The object to store</param> /// <returns>The node that the object is stored in</returns> public HeapNode <TPriority, TItem> Insert(TPriority priority, TItem value) { // Add node as first item in root nodes HeapNode <TPriority, TItem> node = new HeapNode <TPriority, TItem>(priority, value); Trees.AddFirst(node); // Update minimum if (Count == 0 || // Node is first node inserted? Its minimum node.Priority.CompareTo(Minimum.Priority) < 0) // Node is less than current minimum? Its minimum { minimumTreesNode = Trees.First; } Count++; return(node); }
/// <summary> /// Decreases the priority of the given node. O(log n) operation /// </summary> /// <param name="node">The node to decrease the value of</param> /// <param name="priority">The new priority of the node</param> public void DecreasePriority(HeapNode <TPriority, TItem> node, TPriority priority) { // If node priority is already less than given priority if (node.Priority.CompareTo(priority) < 0) { throw new ArgumentException("Priority is not less than current priority"); } // Decrease key of node node.Priority = priority; // If node is a root node, AND its priority is less than the current minimum if (node.Parent == null && priority.CompareTo(Minimum.Priority) < 0) { minimumTreesNode = Trees.Find(node); // Set as minimum } // Is heap order violated? if (node.Parent != null && node.Priority.CompareTo(node.Parent.Priority) < 0) { // Cut from parent and move to root (remember ref to old parent). Node becomes unmarked in the process HeapNode <TPriority, TItem> parent = MoveToRoot(node); // Is new priority less than minimum? if (priority.CompareTo(Minimum.Priority) < 0) { minimumTreesNode = Trees.First; // Node is first element in trees list } // If parent is unmarked, mark it if (!parent.Marked) { parent.Marked = true; } else // Parent IS already marked { // Cut parent, move to root, DO FOR ALL ANCESTORS while (parent != null && parent.Marked) { parent = MoveToRoot(parent); // Move to root, check its parent } } } }
// изменить приоритет public void DecreasePriority(HeapNode <TPriority, TItem> node, TPriority priority) { // если св-во кочи сохраняются if (node.Priority.CompareTo(priority) < 0) { throw new ArgumentException(); } // изменить приоритет node.Priority = priority; // если node корневвой узел и его приоритет меньше приритета min - он минимум if (node.Parent == null && priority.CompareTo(Minimum.Priority) < 0) { minimumTreesNode = Trees.Find(node); } // если порядок кучи нарушен if (node.Parent != null && node.Priority.CompareTo(node.Parent.Priority) < 0) { // поместить node в корневой список HeapNode <TPriority, TItem> parent = MoveToRoot(node); if (priority.CompareTo(Minimum.Priority) < 0) { minimumTreesNode = Trees.First; } // отметить родителя если еще не отмечен if (!parent.Marked) { parent.Marked = true; } // если уже отмечен то сделать вырезание и для родителей которые уже отмечены else { while (parent != null && parent.Marked) { parent = MoveToRoot(parent); } } } }
// удалить дочерний узел public void RemoveChild(HeapNode <TPriority, TItem> child) { Children.Remove(child); child.Parent = null; }
// добавить узел как потомок данного узла public void AddChild(HeapNode <TPriority, TItem> node) { Children.Add(node); node.Parent = this; }