// вырезание узла
        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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
             }
         }
     }
 }
Beispiel #7
0
 // удалить дочерний узел
 public void RemoveChild(HeapNode <TPriority, TItem> child)
 {
     Children.Remove(child);
     child.Parent = null;
 }
Beispiel #8
0
 // добавить узел как потомок данного узла
 public void AddChild(HeapNode <TPriority, TItem> node)
 {
     Children.Add(node);
     node.Parent = this;
 }