Exemplo n.º 1
0
        public override void DeleteMin()
        {
#if VERBOSE
            Console.WriteLine("Current min ({0}:{1}:{2}) >>",
                              _roots.Count(r => r != null),
                              _consolidateRoots == null ? 0 : _consolidateRoots.GetSiblings().Count(),
                              Count);
            Console.WriteLine(_minNode == null ? string.Empty : _minNode.ToString(_traversalActions));
            Console.WriteLine(">> Delete-Min");
#endif

            LastConsolidateDepth = 0;

            if (Count == 0)
            {
                return;
            }

            if (Count == 1)
            {
                Debug.Assert(_minNode.FirstChild == null);
                Debug.Assert(_minNode.LeftSibling == _minNode.RightSibling && _minNode.RightSibling == _minNode);
                _minNode.Dispose();
                _minNode          = null;
                _consolidateRoots = null;
                Debug.Assert(_roots.Count == 1);
                _roots.Stretch(0);
                Count = 0;
                return;
            }

            Debug.Assert(_minNode != null);
            Debug.Assert(_minNode.LeftSibling != null && _minNode.RightSibling != null);


            // Remove min from its list and gut it
            var children = (HeapNode)_minNode.FirstChild;

            // Cut the minimum from roots
            if (_roots[_minNode.Order] == _minNode)
            {
                _roots[_minNode.Order] = null;
            }
            else
            {
                // MinNode must be among nodes to be consolidated
                Debug.Assert(_consolidateRoots.GetSiblings().Contains(_minNode));

                if (_minNode.RightSibling == _minNode)
                {
                    _consolidateRoots = null; // It is the only consolidated root -- remove it
                }
                else
                {
                    _consolidateRoots = (HeapNode)_minNode.RightSibling;
                }
            }

            // Remove from family -- preserves children
            _minNode.CutFromFamily();
            _minNode.Dispose();
            _minNode = null;
            Count--;


            // Make min's children into roots
            if (children != null)
            {
                Debug.Assert(children.LeftSibling != null && children.RightSibling != null);
                children.Parent = null;
                AddForConsolidation(children);
            }

            // Combine roots and find the new minimum
            Consolidate();
        }