How to Merge sort a Linked List with O(nlogn) time and O(1) space complexity

余生长醉 提交于 2019-12-05 17:05:34

Your recursive approach requires Θ(log n) extra space, since you'll have Θ(log n) calls on the stack when you're all the way down to merge-sorting a singleton-list.

To reduce it to O(1) extra space, you'll need to change from a recursive "top-down" approach, where you split the list into two large sublists, sort them, and merge the results — giving you a recursive depth of Θ(log n) — to an iterative "bottom-up" approach where you first sort all the singleton-lists, then all the pairs (the first and second elements, then the third and fourth, etc.), then all the quartets (the first through fourth elements, then the fifth through eighth, etc.) — giving you Θ(log n) passes through the list. Each pass takes Θ(n) time, so the total time is still Θ(n log n).

So overall, you'll have three methods:

  • Node merge(Node listA, Node listB), which you've already written.

  • Node mergePass(Node list, int i):

    • precondition: nodes #1 to #n are sorted, nodes #(n+1) to #(2n) are sorted, etc.
    • postcondition: nodes #1 to #(2n) are sorted, nodes #(2n+1) to #(4n) are sorted, etc.
    • works by grabbing nodes #1 to #n and nodes #(n+1) to #(2n), "cutting" them out, calling merge, and "pasting" the result in; then doing the same for nodes #(2n+1) to #(3n) and nodes #(3n+1) to #(4n); etc.
  • Node mergeSort(Node list):

    • calls mergePass(..., 1) on its argument.
    • calls mergePass(..., 2) on the result, then calls mergePass(..., 4) on that result, etc., doubling i each time.
    • stops before i is the length of the list (or bigger), since mergePass(..., i) is a no-op if i is that big.
    • returns the last result.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!