【发布时间】:2016-02-15 10:14:21
【问题描述】:
如何知道我是否在链表上的合并排序实现中使用了 O(nlog(n))。我应该向 O(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;
}
【问题讨论】:
-
你需要分析你的算法。与 N=256 相比,您将循环遍历 N=16 的排序代码多少次?
-
例如,我的列表中有 100 个元素,我需要知道它将通过 O(n*log(n)) 循环多少次。
-
O(n*log(n)) 是一个近似值,而不是计算您的方法将循环的 精确 次的函数。见:stackoverflow.com/questions/3255/…
-
Wiki 有一个自下而上的链表排序示例,它避免了扫描列表以找到列表的中间部分。 wiki linked list sort。 wiki 示例类似于 Microsoft C++ STL 如何实现 std::list::sort。
标签: c# algorithm sorting mergesort