/// <summary>
        /// Time complexity: O(log(n)).
        /// </summary>
        public T Extract()
        {
            if (heapForest.Head == null)
            {
                throw new Exception("Empty heap");
            }

            var minMaxTree = heapForest.Head;
            var current    = heapForest.Head;

            //find minMaximum tree
            while (current.Next != null)
            {
                current = current.Next;

                if (comparer.Compare(minMaxTree.Data.Value, current.Data.Value) > 0)
                {
                    minMaxTree = current;
                }
            }

            //remove tree root
            heapForest.Delete(minMaxTree);

            var newHeapForest = new DoublyLinkedList <BinomialHeapNode <T> >();

            //add removed roots children as new trees to forest
            foreach (var child in minMaxTree.Data.Children)
            {
                child.Parent = null;
                newHeapForest.InsertLast(child);
            }

            mergeSortedForests(newHeapForest);

            meld();

            removeMapping(minMaxTree.Data.Value, minMaxTree.Data);

            Count--;

            return(minMaxTree.Data.Value);
        }
        /// <summary>
        /// Merge roots with same degrees in Forest
        /// </summary>
        private void Meld()
        {
            if (heapForest.Head == null)
            {
                return;
            }

            var cur  = heapForest.Head;
            var next = heapForest.Head.Next;

            //TODO
            while (next != null)
            {
                //case 1
                //degrees are differant
                //we are good to move ahead
                if (cur.Data.Degree != next.Data.Degree)
                {
                    cur  = next;
                    next = cur.Next;
                }
                //degress of cur & next are same
                else
                {
                    //case 2 next degree equals next-next degree
                    if (next.Next != null &&
                        cur.Data.Degree == next.Next.Data.Degree)
                    {
                        cur  = next;
                        next = cur.Next;
                        continue;
                    }

                    //case 3 cur value is less than next
                    if (cur.Data.Value.CompareTo(next.Data.Value) >= 0)
                    {
                        //add next as child of current
                        cur.Data.Children.Add(next.Data);
                        next.Data.Parent = cur.Data;
                        heapForest.Delete(next);

                        next = cur.Next;

                        continue;
                    }

                    //case 4 cur value is greater than next
                    if (cur.Data.Value.CompareTo(next.Data.Value) >= 0)
                    {
                        continue;
                    }

                    //add current as child of next
                    next.Data.Children.Add(cur.Data);
                    cur.Data.Parent = next.Data;

                    heapForest.Delete(cur);

                    cur  = next;
                    next = cur.Next;
                }
            }
        }