/// <summary>
        /// search insert point p,
        /// new key are inserted after p & all the key before p(p is included) are smaller then key
        /// p can't be null, because each list have min & max
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public SkipListNode <K, V> SearchInsertPoint(K key)
        {
            SkipListNode <K, V> node        = head;
            SkipListNode <K, V> insertPoint = null;

            while (node != null)
            {
                if (node.IsMaxNode)
                {
                    break;
                }

                if (node.IsMinNode)
                {
                    insertPoint = node;
                    node        = node.Next;
                    continue;
                }

                if (node.Key.CompareTo(key) < 0)
                {
                    insertPoint = node;
                    node        = node.Next;
                }
                else
                {
                    break;
                }
            }

            return(insertPoint);
        }
        /// <summary>
        /// find the first item . if not found,return null
        /// it runs at O(n)
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public SkipListNode <K, V> Search(K key)
        {
            SkipListNode <K, V> node = head;

            while (node != null)
            {
                if (node.IsMaxNode)
                {
                    node = null;
                    break;
                }

                if (node.IsMinNode)
                {
                    node = node.Next;
                    continue;
                }

                if (node.Key.CompareTo(key) == 0)
                {
                    return(node);
                }

                if (node.Key.CompareTo(key) > 0)
                {
                    return(null);
                }

                node = node.Next;
            }

            return(node);
        }
        /// <summary>
        /// find the node, if not found, return null
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public SkipListNode <K, V> Search(K key)
        {
            if (supportList.Count <= 0)
            {
                return(null);
            }

            SortedSkipLinkedList <K, V> sh = supportList[supportList.Count - 1];

            if (sh.HeadNode == null)
            {
                return(null);
            }

            SkipListNode <K, V> node      = sh.HeadNode;
            SkipListNode <K, V> rightNode = node.Next;

            while (true)
            {
                //reach to end
                if (rightNode.IsMaxNode)
                {
                    node = node.Down;
                    if (node == null)
                    {
                        return(null);
                    }
                    else
                    {
                        rightNode = node.Next;
                        continue;
                    }
                }

                int result = rightNode.Key.CompareTo(key);
                if (result == 0)
                {
                    return(rightNode);
                }
                else if (result >= 0)
                {
                    node = node.Down;
                    if (node == null)
                    {
                        return(null);
                    }
                    else
                    {
                        rightNode = node.Next;
                    }
                }
                else
                {
                    node      = node.Next;
                    rightNode = node.Next;
                }
            }
        }
        /// <summary>
        /// insert item into list, it runs at O(n)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void Insert(K key, V val)
        {
            Count++;

            SkipListNode <K, V> newNode = new SkipListNode <K, V>(key, val);

            SkipListNode <K, V> insertPoint = SearchInsertPoint(key);

            newNode.Next          = insertPoint.Next;
            insertPoint.Next.Prev = newNode;
            newNode.Prev          = insertPoint;
            insertPoint.Next      = newNode;
        }
 public SortedSkipLinkedList()
 {
     head = new SkipListNode <K, V>()
     {
         IsMinNode = true
     };
     tail = new SkipListNode <K, V>()
     {
         IsMaxNode = true
     };
     head.Next = tail;
     tail.Prev = head;
 }
        /// <summary>
        /// delete from list
        /// </summary>
        /// <param name="node"></param>
        public void Delete(SkipListNode <K, V> node)
        {
            if (node == null)
            {
                return;
            }

            if (node.IsMinNode || node.IsMaxNode)
            {
                return;
            }

            Count--;

            node.Prev.Next = node.Next;
            node.Next.Prev = node.Prev;
        }
        /// <summary>
        /// if &gt; other, return 1; &lt; other return -1; == other ,return 0
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(SkipListNode <K, V> other)
        {
            if (IsMaxNode && other.IsMaxNode)
            {
                throw new Exception("can't be both max");
            }

            if (IsMinNode && other.IsMinNode)
            {
                throw new Exception("can't be both min");
            }

            if (IsMaxNode)
            {
                return(1);
            }

            if (IsMinNode)
            {
                return(-1);
            }

            return(this.Key.CompareTo(other.Key));
        }
        /// <summary>
        /// if randonDecision = true, increase height by 1, else just insert
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void Insert(K key, V val)
        {
            Count++;

            bool decision = RandomDecision();

            int height = 1;

            while (decision)
            {
                //increase height by 1;
                height++;
                decision = RandomDecision();
            }

            while (supportList.Count < height)
            {
                var listn = new SortedSkipLinkedList <K, V>();
                if (supportList.Count > 0)
                {
                    var listn_1 = supportList[supportList.Count - 1];
                    listn_1.HeadNode.Up = listn.HeadNode;
                    listn.HeadNode.Down = listn_1.HeadNode;
                    listn_1.TailNode.Up = listn.TailNode;
                    listn.TailNode.Down = listn_1.TailNode;
                }
                supportList.Add(listn);
            }

            //the height column
            var sh          = supportList[height - 1];
            var insertPoint = sh.SearchInsertPoint(key);

            SkipListNode <K, V> upNode = null;

            while (insertPoint != null)
            {
                var newNode = new SkipListNode <K, V>(key, val);
                newNode.Next          = insertPoint.Next;
                newNode.Prev          = insertPoint;
                insertPoint.Next.Prev = newNode;
                insertPoint.Next      = newNode;
                sh.Count++;
                if (upNode != null)
                {
                    upNode.Down = newNode;
                    newNode.Up  = upNode;
                }
                upNode = newNode;

                insertPoint = insertPoint.Down;

                if (insertPoint == null)
                {
                    break;
                }
                var rightNode = insertPoint.Next;
                while (true)
                {
                    if (rightNode.IsMaxNode)
                    {
                        break;
                    }

                    if (rightNode.Key.CompareTo(key) < 0)
                    {
                        insertPoint = rightNode;
                        rightNode   = insertPoint.Next;
                    }
                    else
                    {
                        break;
                    }
                }
                height--;
                sh = supportList[height - 1];
            }
        }
 /// <summary>
 /// is equal
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public bool Equals(SkipListNode <K, V> other)
 {
     return(CompareTo(other) == 0);
 }