Пример #1
0
        /// <summary>
        /// Merge two subheaps together.
        /// </summary>
        /// <param name="x">The parent of the first subheap.</param>
        /// <param name="y">The parent of the second subheap.</param>
        /// <returns>The merged heap.</returns>
        public FibonacciHeapNode <T> Merge(FibonacciHeapNode <T> x, FibonacciHeapNode <T> y)
        {
            if (x == null && y == null)
            {
                return(null);
            }
            else if (x != null && y == null)
            {
                return(x);
            }
            else if (x == null && y != null)
            {
                return(y);
            }
            else
            {
                FibonacciHeapNode <T> xOldRight = x.Right;
                x.Right      = y.Right;
                x.Right.Left = x;
                y.Right      = xOldRight;
                y.Right.Left = y;

                return(x.Key > y.Key? x : y);
            }
        }
Пример #2
0
        public T DequeueMin()
        {
            _size--;

            //store old minimum node
            FibonacciHeapNode <T> oldMin = _minimumNode;

            if (_minimumNode.Right == _minimumNode)
            {
                _minimumNode = null;
            }
            else
            {
                _minimumNode.Left.Right = _minimumNode.Right;
                _minimumNode.Right.Left = _minimumNode.Left;
                _minimumNode            = _minimumNode.Right;
            }

            //delete the parent reference of all childs of the old minimum node
            if (oldMin.Child != null)
            {
                FibonacciHeapNode <T> current = oldMin.Child;
                while (current != null)
                {
                    current.Parent = null;
                    current        = current.Right;
                }
            }

            _minimumNode = Merge(_minimumNode, oldMin.Child);

            return(oldMin.Element);
        }
Пример #3
0
 public void Clear()
 {
     _minimumNode = null;
     _size        = 0;
     _trees       = 0;
     _markedNodes = 0;
     _allElements.Clear();
 }
Пример #4
0
 public FibonacciHeapNode(T element, int key)
 {
     _degree       = 0;
     _left         = this;
     _right        = this;
     _marked       = false;
     this._element = element;
     Key           = key;
 }
Пример #5
0
        public bool Add(T element, int key)
        {
            if (element == null)
            {
                throw new ArgumentException("Elememts to add are not allowed to be null.");
            }

            FibonacciHeapNode <T> node = new FibonacciHeapNode <T>(element, key);

            MoveToRoot(node);

            _size++;

            _allElements.Add(element);

            return(true);
        }
Пример #6
0
        private void MoveToRoot(FibonacciHeapNode <T> node)
        {
            if (IsEmpty())
            {
                _minimumNode = node;
            }
            else
            {
                node.Left.Right = node.Right;
                node.Right.Left = node.Left;

                node.Left          = _minimumNode;
                node.Right         = _minimumNode.Right;
                _minimumNode.Right = node;
                node.Right.Left    = node;

                if (node.Key > _minimumNode.Key)
                {
                    _minimumNode = node;
                }
            }
        }
Пример #7
0
        public void Consolidate()
        {
            //if the heap is empty now, the procedure is finished
            if (_minimumNode == null)
            {
                return;
            }

            //save info of top level
            List <FibonacciHeapNode <T> > treeTable = new List <FibonacciHeapNode <T> >();

            //cache parts of the heap we need to visit again
            List <FibonacciHeapNode <T> > toVisit = new List <FibonacciHeapNode <T> >();

            //fill toVisit list
            for (FibonacciHeapNode <T> current = _minimumNode;
                 toVisit.Count == 0 || toVisit[0] != current;
                 current = current.Right)
            {
                toVisit.Add(current);
            }

            //combine pairwise
            foreach (FibonacciHeapNode <T> current in toVisit)
            {
                FibonacciHeapNode <T> tocompare = current;
                while (true)
                {
                    //keep treeTable at a proper size
                    while (current.Degree >= treeTable.Count)
                    {
                        treeTable.Add(null);
                    }

                    if (treeTable[current.Degree] == null)
                    {
                        treeTable[current.Degree] = current;
                        break;
                    }

                    //if conflict, merge them
                    FibonacciHeapNode <T> other = treeTable[current.Degree];
                    treeTable[current.Degree] = null;

                    FibonacciHeapNode <T> smaller = current.Key > other.Key? other : current;
                    FibonacciHeapNode <T> bigger  = current.Key > other.Key ? current : other;

                    bigger.Right.Left = bigger.Left;
                    bigger.Left.Right = bigger.Right;
                    bigger.Right      = bigger.Left = bigger;
                    smaller.Child     = Merge(smaller.Child, bigger);
                    bigger.Parent     = smaller;
                    bigger.Marked     = false;

                    //increase Degree
                    smaller.IncreaseDegree();

                    tocompare = smaller;
                }

                if (tocompare.Key > _minimumNode.Key)
                {
                    _minimumNode = current;
                }
            }
        }