如何从合并排序中获得O(n log(n))?

时间:2016-02-15 10:14:21

标签: c# algorithm sorting mergesort

如何知道我是否在链表上的合并排序实现中使用O(nlog(n))。我应该输入什么(n(nlog(n))才能知道我在合并排序时实现的时间。

public static LinkedListNode<T> MergeSortLL<T>(LinkedListNode<T> Head) where T : IComparable<T>
{

    if (Head?.Next == null)
    {
        return Head;
    }
    var middle = GetMiddle(Head);
    var half = middle.Next;
    middle.Next = null;

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

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?.Next != null)
    {
        slow = slow.Next;
        fast = fast.Next.Next;
    }
    return slow;
}

2 个答案:

答案 0 :(得分:2)

请注意,已知此算法可执行O(N * log(N))比较。如果你想确认(因为它已被证实),你可以放一个计数器并在每次比较时增加它。

例如

public static int Comparisons;

public static LinkedListNode<T> Merge<T>(LinkedListNode<T> Left, LinkedListNode<T> Right) where T : IComparable<T>
{
    // ...
    Comparisons++;
    if (Left.Value.CompareTo(Right.Value) <= 0)
    // ...
}

并检查

LinkedListNode<int> head = ...;
Comparisons = 0;
head = MergeSortLL(head);
Debug.Print(Comparisons);

但请注意,此算法也具有显着的隐藏成本(找到中间,即使使用慢/快指针技术)。

答案 1 :(得分:1)

您可以做的是为sort方法添加一个计数器参数(一个引用),并在每次进入循环时递增它。然后将此计数器与您尝试排序的元素数量的复杂性进行比较(让我们称之为N)。然后,您将看到O(N²N)中的O(NlogN)是否更多。

例如,如果您的计数器在尝试对N = 10个元素进行排序时为30,则为 10 * log(10)= 23,02 ...和10²= 100你看到你的O(NlogN)比O(N²)更多。

相关问题