Sorting a linked list

前端 未结 8 751
-上瘾入骨i
-上瘾入骨i 2020-11-29 09:26

I have written a basic linked list class in C#. It has a Node object, which (obviously) represents every node in the list.

The code does not use IEnumerable, however

8条回答
  •  不知归路
    2020-11-29 10:19

    Some people (including me) may have wanted to sort LinkedList from .net library.

    The easy way is to use Linq, sort and finally create a new linked list. but this creates garbage. for small collections it would not be a problem, but for large collections it may not be so efficient.

    for people who want some degree of optimization, here is generic In-place quick sort implementation for .net doubly linked list.

    this implementation does not split/merge, instead it checks nodes for boundaries of each recursion.

    /// 
    /// in place linked list sort using quick sort.
    /// 
    public static void QuickSort(this LinkedList linkedList, IComparer comparer)
    {
        if (linkedList == null || linkedList.Count <= 1) return; // there is nothing to sort
        SortImpl(linkedList.First, linkedList.Last, comparer);
    }
    
    private static void SortImpl(LinkedListNode head, LinkedListNode tail, IComparer comparer)
    {
        if (head == tail) return; // there is nothing to sort
    
        void Swap(LinkedListNode a, LinkedListNode b)
        {
            var tmp = a.Value;
            a.Value = b.Value;
            b.Value = tmp;
        }
    
        var pivot = tail;
        var node = head;
        while (node.Next != pivot)
        {
            if (comparer.Compare(node.Value, pivot.Value) > 0)
            {
                Swap(pivot, pivot.Previous);
                Swap(node, pivot);
                pivot = pivot.Previous; // move pivot backward
            }
            else node = node.Next; // move node forward
        }
        if (comparer.Compare(node.Value, pivot.Value) > 0)
        {
            Swap(node, pivot);
            pivot = node;
        }
    
        // pivot location is found, now sort nodes below and above pivot.
        // if head or tail is equal to pivot we reached boundaries and we should stop recursion.
        if (head != pivot) SortImpl(head, pivot.Previous, comparer);
        if (tail != pivot) SortImpl(pivot.Next, tail, comparer);
    }
    

提交回复
热议问题