private void Concatenate(PairingHeap <T> priorityQueue)
        {
            if (null == priorityQueue || null == priorityQueue.head)
            {
                return;
            }

            if (null == head)
            {
                head          = priorityQueue.head;
                priorityQueue = null;
                return;
            }

            if (head != priorityQueue.head)
            {
                if (!compareFunctor(head.Value, priorityQueue.head.Value))
                {
                    AddChildNode(priorityQueue.head);
                }
                else
                {
                    priorityQueue.AddChildNode(head);
                    head = priorityQueue.head;
                }
            }
            priorityQueue = null;
        }
        public (bool HasValue, T value) ExtractMinimum()
        {
            if (null == head)
            {
                return(false, default(T));
            }

            var prevHead    = head;
            T   returnValue = head.Value;

            if (null == head.child)
            {
                head = null;
                return(true, returnValue);
            }

            head = head.child;

            prevHead.last  = true;
            prevHead.child = null;
            prevHead.left  = null;
            prevHead.right = null;

            head.last = true;
            Node <T> nodeToMerge = head.right;

            head.right = null;
            head.left  = null;

            while (null != nodeToMerge)
            {
                var mergedNode = nodeToMerge;
                nodeToMerge      = nodeToMerge.right;
                mergedNode.right = null;
                mergedNode.left  = null;
                mergedNode.last  = true;
                PairingHeap <T> queueToMerge = new PairingHeap <T>(mergedNode, compareFunctor);
                Concatenate(queueToMerge);
            }

            return(true, returnValue);
        }