import random def merge_sort(xs): """Inplace merge sort of array without recursive. The basic idea is to avoid the recursive call while using iterative solution. The algorithm first merge chunk of length of 2, then merge chunks of length 4, then 8, 16, .... , until 2^k where 2^k is large than the length of the array """ unit = 1 while unit <= len(xs): h = 0 for h in range(0, len(xs), unit * 2): l, r = h, min(len(xs), h + 2 * unit) mid = h + unit # merge xs[h:h + 2 * unit] p, q = l, mid while p < mid and q < r: if xs[p] < xs[q]: p += 1 else: tmp = xs[q] xs[p + 1: q + 1] = xs[p:q] xs[p] = tmp p, mid, q = p + 1, mid + 1, q + 1 unit *= 2 return xs def test(): assert merge_sort([4,3,2,1]) == [1,2,3,4] assert merge_sort([4,2,3,1]) == [1,2,3,4] assert merge_sort([4,5,3,2,1]) == [1,2,3,4,5] for _ in range(100): tmp = range(100) random.shuffle(tmp) assert merge_sort(tmp) == range(100) return 'test pass!'