/// <summary>
        /// Merges two ordered sublists
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="aNode">Left part of sublist</param>
        /// <param name="bNode">Right part of sublist</param>
        /// <param name="tailNode">Tail node of the merged list</param>
        /// <returns>The result of merging</returns>
        private static DataStructures.Linear.LinkedListNode <T> Merge <T>(DataStructures.Linear.LinkedListNode <T> leftNode,
                                                                          DataStructures.Linear.LinkedListNode <T> rightNode,
                                                                          ref DataStructures.Linear.LinkedListNode <T> tailNode) where T : IComparable <T>
        {
            var dummyHead = new DataStructures.Linear.LinkedListNode <T>();
            var curNode   = dummyHead;

            while (leftNode != null || rightNode != null)
            {
                if (rightNode == null)
                {
                    curNode.Next = leftNode;
                    leftNode     = leftNode.Next;
                }
                else if (leftNode == null)
                {
                    curNode.Next = rightNode;
                    rightNode    = rightNode.Next;
                }
                else if (leftNode.Value.CompareTo(rightNode.Value) <= 0)
                {
                    curNode.Next = leftNode;
                    leftNode     = leftNode.Next;
                }
                else
                {
                    curNode.Next = rightNode;
                    rightNode    = rightNode.Next;
                }
                curNode = curNode.Next;
            }
            tailNode = curNode;
            return(dummyHead.Next);
        }
        /// <summary>
        /// Returns the sentinel node
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="firstNode"></param>
        /// <returns></returns>
        private static DataStructures.Linear.LinkedListNode <T> GetSentinelNode <T>(DataStructures.Linear.LinkedListNode <T> firstNode) where T : IComparable <T>
        {
            var curNode = firstNode;

            while (curNode != null && curNode.Next != null && curNode.Value.CompareTo(curNode.Next.Value) <= 0)
            {
                curNode = curNode.Next;
            }

            return(curNode);
        }
예제 #3
0
        private static DataStructures.Linear.LinkedListNode <T> GetMiddle <T>(DataStructures.Linear.LinkedListNode <T> firstNode) where T : IComparable <T>
        {
            if (firstNode.Next == null)
            {
                return(firstNode);
            }

            DataStructures.Linear.LinkedListNode <T> fast, slow;
            fast = slow = firstNode;
            while (fast.Next != null && fast.Next.Next != null)
            {
                slow = slow.Next;
                fast = fast.Next.Next;
            }
            return(slow);
        }
예제 #4
0
        private static DataStructures.Linear.LinkedListNode <T> ShuffledMerge <T>(DataStructures.Linear.LinkedListNode <T> leftNode, DataStructures.Linear.LinkedListNode <T> rightNode) where T : IComparable <T>
        {
            var dummyHead = new DataStructures.Linear.LinkedListNode <T>();

            DataStructures.Linear.LinkedListNode <T> curNode = dummyHead;

            var rnd = new Random((int)DateTime.Now.Ticks);

            while (leftNode != null || rightNode != null)
            {
                var rndRes = rnd.Next(0, 2);
                if (rndRes == 0)
                {
                    if (leftNode != null)
                    {
                        curNode.Next = leftNode;
                        leftNode     = leftNode.Next;
                    }
                    else
                    {
                        curNode.Next = rightNode;
                        rightNode    = rightNode.Next;
                    }
                }
                else
                {
                    if (rightNode != null)
                    {
                        curNode.Next = rightNode;
                        rightNode    = rightNode.Next;
                    }
                    else
                    {
                        curNode.Next = leftNode;
                        leftNode     = leftNode.Next;
                    }
                }

                curNode = curNode.Next;
            }
            return(dummyHead.Next);
        }
예제 #5
0
        public static DataStructures.Linear.LinkedListNode <T> Shuffle <T>(DataStructures.Linear.LinkedListNode <T> firstNode) where T : IComparable <T>
        {
            if (firstNode == null)
            {
                throw new ArgumentNullException(nameof(firstNode));
            }

            if (firstNode.Next == null)
            {
                return(firstNode);
            }

            var middle    = GetMiddle(firstNode);
            var rightNode = middle.Next;

            middle.Next = null;

            var mergedResult = ShuffledMerge(Shuffle(firstNode), Shuffle(rightNode));

            return(mergedResult);
        }
        public static DataStructures.Linear.LinkedListNode <T> Sort <T>(DataStructures.Linear.LinkedListNode <T> firstNode) where T : IComparable <T>
        {
            if (firstNode is null)
            {
                throw new ArgumentNullException(nameof(firstNode));
            }

            if (firstNode.Next == null)
            {
                return(firstNode);
            }

            var head     = firstNode;
            var leftNode = head;
            var iterNum  = 0;

            while (leftNode != null)
            {
                //Let's start again from the beginning
                leftNode = head;
                iterNum  = 0;
                DataStructures.Linear.LinkedListNode <T> tailNode = null;

                while (leftNode != null)
                {
                    //Let's get the left sublist

                    //Let's find the node which divides sublist into two ordered sublists
                    var sentinelNode = GetSentinelNode(leftNode);
                    var rightNode    = sentinelNode.Next;

                    //If the right node is null it means that we don't have two sublist and the left sublist is ordered already
                    //so we just add the rest sublist to the tail
                    if (rightNode == null)
                    {
                        if (tailNode == null)
                        {
                            break;
                        }
                        tailNode.Next = leftNode;
                        break;
                    }

                    sentinelNode.Next = null;

                    //Let's find the node where the right sublist ends
                    sentinelNode = GetSentinelNode(rightNode);
                    var restNode = sentinelNode.Next;
                    sentinelNode.Next = null;

                    DataStructures.Linear.LinkedListNode <T> newTailNode = null;

                    //Merging of two ordered sublists
                    var mergedList = Merge(leftNode, rightNode, ref newTailNode);
                    //If we're at the beginning of the list the head of the merged sublist becomes the head of the list
                    if (iterNum == 0)
                    {
                        head = mergedList;
                    }
                    else //add the
                    {
                        tailNode.Next = mergedList;
                    }

                    tailNode = newTailNode;
                    leftNode = restNode;
                    iterNum++;
                }
                if (iterNum == 0)
                {
                    break;
                }
            }
            return(head);
        }