//一直插入是一个根列表
        public virtual void Insert(FibonacciNode <T> newNode)
        {
            newNode.Degree = 0;
            newNode.Parent = null;
            newNode.Child  = null;
            newNode.Left   = newNode;
            newNode.Right  = newNode;
            newNode.Mark   = false;

            if (Peak == null)
            {
                Peak = newNode;
            }
            else
            {
                //insert to root list
                AddNode(Peak, newNode);

                if (_com(newNode.Key, Peak.Key))
                {
                    Peak = newNode;
                }
            }

            Length = Length + 1;
        }
        //这么基本的操作都有点搞不清,只是交换值不会有什么影响

        public void Exchange(ref FibonacciNode <T> x, ref FibonacciNode <T> y)
        {
            var temp = x;

            x = y;
            y = temp;
        }
 public void Traverse(FibonacciNode <T> startNode, Action <FibonacciNode <T> > action)
 {
     foreach (var item in TraverseList(startNode))
     {
         action(item);
         Traverse(item.Child, action);
     }
 }
        public virtual FibonacciNode <T> Insert(T key)
        {
            var node = new FibonacciNode <T>();

            node.Key = key;
            Insert(node);
            return(node);
        }
        /// <summary>
        /// 将新节点插入到双向环形链表
        /// </summary>
        /// <param name="root"></param>
        /// <param name="newNode"></param>
        private void AddNode(FibonacciNode <T> root, FibonacciNode <T> newNode)
        {
            //将新节点插入到根某节点的Left。

            newNode.Left    = root.Left;
            root.Left.Right = newNode;

            newNode.Right = root;
            root.Left     = newNode;
        }
        /// <summary>
        /// 合并两个双向环形链表
        /// </summary>
        /// <param name="root"></param>
        /// <param name="newRoot"></param>
        private void LinkedIn(FibonacciNode <T> root, FibonacciNode <T> newRoot)
        {
            //交换两个链表的Right。
            //因为是环形的保证可以合并成一个新的链表

            var temp = root.Right;

            root.Right         = newRoot.Right;
            newRoot.Right.Left = root;

            newRoot.Right = temp;
            temp.Left     = newRoot;
        }
        /// <summary>
        /// 不要在回修改引用的情况下使用这个方法
        /// </summary>
        /// <param name="startNode"></param>
        /// <param name="action"></param>
        public IEnumerable <FibonacciNode <T> > TraverseList(FibonacciNode <T> node)
        {
            if (node == null)
            {
                yield break;
            }
            var temp = node;

            do
            {
                yield return(temp);

                temp = temp.Left;
            }while (temp != node);
        }
        private void CascadingCut(FibonacciNode <T> node)
        {
            var parent = node.Parent;

            if (parent != null)
            {
                if (!node.Mark)
                {
                    node.Mark = true;
                }
                else
                {
                    Cut(node, parent);
                    CascadingCut(parent);
                }
            }
        }
        //不能使用 yield ,各种修改引用很容易出问题。

        private IEnumerable <FibonacciNode <T> > GetList(FibonacciNode <T> node)
        {
            var result = new List <FibonacciNode <T> >();

            if (node == null)
            {
                return(result);
            }
            var temp = node;

            do
            {
                result.Add(temp);
                temp = temp.Left;
            }while (temp != node);

            return(result);
        }
        private void Link(FibonacciNode <T> child, FibonacciNode <T> parent)
        {
            DeleteNode(child);

            if (parent.Child == null)
            {
                parent.Child = child;
                child.Left   = child;
                child.Right  = child;
            }
            else
            {
                AddNode(parent.Child, child);
            }
            child.Parent = parent;

            parent.Degree += 1;
            child.Mark     = false;
        }
        private void Cut(FibonacciNode <T> node, FibonacciNode <T> parent)
        {
            //更新Child

            if (parent.Degree == 1)
            {
                parent.Child = null;
            }
            else if (parent.Child == node)
            {
                parent.Child = node.Right;
            }

            DeleteNode(node);
            parent.Degree = parent.Degree - 1;

            AddNode(Peak, node);
            node.Parent = null;
            node.Mark   = false;
        }
        /// <summary>
        /// Increase和Decrease
        /// </summary>
        /// <param name="oldKey"></param>
        /// <param name="newKey"></param>
        public void UpdateKey(FibonacciNode <T> node, T newKey)
        {
            if (_com(node.Key, newKey))
            {
                return;
            }

            node.Key = newKey;

            var parent = node.Parent;

            if (parent != null && _com(node.Key, parent.Key))
            {
                Cut(node, parent);
                CascadingCut(parent);
            }
            if (_com(node.Key, Peak.Key))
            {
                Peak = node;
            }
        }
        //双向环形链表有很多好处

        private void DeleteNode(FibonacciNode <T> node)
        {
            node.Right.Left = node.Left;

            node.Left.Right = node.Right;
        }
 /// <summary>
 /// 因为是泛型不能取最小值,所以暂时不提供删除
 /// </summary>
 /// <param name="node"></param>
 public void Delete(FibonacciNode <T> node)
 {
 }
        /// <summary>
        /// 连接跟节点,使每个度最多只有一个根节点
        /// </summary>
        //使(成串地)连结[衔接]起来
        private void Concatenate()
        {
            var degreeArray = new FibonacciNode <T> [DegreeCountBound];

            var roots = GetList(Peak).ToList();

            foreach (var root in roots)
            {
                var currentNode = root;
                var degree      = currentNode.Degree;

                //将相同degree的Node合并成树。

                while (degreeArray[degree] != null)
                {
                    var oldNode = degreeArray[degree];

                    //构建一个有序树。

                    if (_com(oldNode.Key, currentNode.Key))
                    {
                        Exchange(ref currentNode, ref oldNode);
                    }

                    Link(oldNode, currentNode);

                    degreeArray[degree] = null;
                    degree = degree + 1;
                }

                degreeArray[degree] = currentNode;
            }

            #region    //new peak and root list

            Peak = null;

            foreach (var item in degreeArray)
            {
                if (item != null)
                {
                    if (Peak == null)
                    {
                        //这个操作比较重要,新的root节点left和right都指向自己
                        item.Left  = item;
                        item.Right = item;
                        Peak       = item;
                    }

                    else
                    {
                        AddNode(Peak, item);
                        if (_com(item.Key, Peak.Key))
                        {
                            Peak = item;
                        }
                    }
                }
            }

            #endregion
        }