如何修改合并排序到位?

时间:2017-09-11 14:47:56

标签: algorithm mergesort

我正在寻找一种将合并排序修改为就地排序算法的算法。我试图改变索引而不是拆分数组,但是陷入了合并阶段。

1 个答案:

答案 0 :(得分:0)

迭代合并排序是 O(1)空间复杂性的朋友。

这是Python的实现:

def merge_sort_in_place(alist):
    i = 1
    while i <= len(alist):
        j = 0
        for j in range(0, len(alist), i * 2):
            left, right = j, min(len(alist), j + 2 * i)
            mid = j + i
            p, q = left, mid
            while p < mid and q < right:
                if alist[p] < alist[q]: # already sorted...
                    p += 1 # ... skip to next pair
                else: # need to swap...
                    temp = alist[q] # store temp value...
                    alist[p + 1: q + 1] = alist[p:q] # ... shift to the right...
                    alist[p] = temp # update value
                    p, mid, q = p + 1, mid + 1, q + 1 # ... go to next pair
        i *= 2
    return alist

测试出来:

import random

big_num = 2**15
l = list(range(big_num))
random.shuffle(l)

assert(merge_sort_in_place(l) == list(range(big_num)))
print("It sorts!")

[3, 1, 4, 0, 2, 5]为例,看看交换发生时内部while循环的作用:

We start with: [3, 1, 4, 0, 2, 5]
when: p = 0, q = 1, mid = 1  -->  [1, 3, 4, 0, 2, 5]
when: p = 2, q = 3, mid = 3  -->  [1, 3, 0, 4, 2, 5]
when: p = 0, q = 2, mid = 2  -->  [0, 1, 3, 4, 2, 5]
when: p = 2, q = 4, mid = 4  -->  [0, 1, 2, 3, 4, 5]