Search code examples
c#genericslinked-listmergesort

Merge sort in generic single linked list


Having some troubles with sorting, while debugging, I've found interesting thing that in method Merge the return data is correct, and then it join to MergeSortLL method and show that Head have only one node there while it must to have for ex. 5 sorted node. What could I miss here?

public static LinkedListNode<T> MergeSortLL<T>(LinkedListNode<T> Head) where T : IComparable<T>
{           
    if (Head == null || Head.Next == null)
        return Head;

    LinkedListNode<T> middle = GetMiddle(Head);
    LinkedListNode<T> half = middle.Next;
    middle.Next = null;

    return Merge(MergeSortLL(Head), MergeSortLL(half));
}

            public static LinkedListNode<T> Merge<T>(LinkedListNode<T> Left, LinkedListNode<T> Right) where T : IComparable<T>
            {

                var mHead = new LinkedListNode<T>(default(T));
                LinkedListNode<T> curr = mHead;

                while (Left != null && Right != null)
                {
                    if (Left.Value.CompareTo(Right.Value) <= 0)
                    {
                        curr.Next = Left;
                        Left = Left.Next;
                    }
                    else
                    {
                        curr.Next = Right;
                        Right = Right.Next;
                    }
                    curr = curr.Next;
                }
                curr.Next = (Left == null) ? Right : Left;

                return mHead.Next;
            }

            public static LinkedListNode<T> GetMiddle<T>(LinkedListNode<T> Head) where T : IComparable<T>
            {
                if (Head == null)
                {
                    return Head;
                }

                LinkedListNode<T> slow, fast;
                slow = fast = Head;

                while (fast.Next != null && fast.Next.Next != null)
                {
                    slow = slow.Next;
                    fast = fast.Next.Next;
                }
                return slow;
            }

Solution

  • What could I miss here?

    You are missing that the method modified the links and returns the new head, so it's normal the old head to show less or zero next elements.

    It would be more obvious if you replace this

    return Merge(MergeSortLL(Head), MergeSortLL(half));
    

    with

    Head = Merge(MergeSortLL(Head), MergeSortLL(half));
    return Head;
    

    Also don't forget to do the same in the external calls, e.g.

    LinkedListNode<int> head = ...;
    head = MergeSortLL(head);