sort,也就是原地归并排序。
在进入具体的细节之前,先来看一个稍后会用到的引论 :
给定长度分别为n和m的两个各自有序数组X,Y,以及一个长度为n的辅助数组A,存在O(m+n)时间复杂度的算法AuxSort;该算法可以原地归并排序X和Y,同时A中元素保持不变(顺序可能打乱)。
看到留言说用了辅助数组A,空间复杂度就是O(n)了。所以先提前在这解释下:AuxSort算法中确实用到了长度为n的辅助数组A。但是在最终的算法
中,AuxSort会作为subroutine,而我们会将待排序数组的一部分作为这个辅助数组A,而不是另外开辟一块空间。所以最终的空间复杂度仍然是
O(1)。所以请大家耐心往下看。。。
AuxSort算法具体步骤如下:
交换X 和 A。
维护两个整数下标 px, py,初始化为0,分别代表A[0]和Y[0]; 另外维护一个dest指针,初始化指向X[0],并且该指针在移动到X[n-1]后,自动过渡到Y[0]。
比较A[px], Y[py]:
若 A[px] <= Y[py], swap(A[px++], *dest++);
若 A[px] > Y[py],swap(Y[py++], *dest++);
若A中仍有剩余元素,则将剩余部分依次与*dest交换。当然每一步要执行dest++操作。【Y中有剩余元素不必再操作了,此时已经保持有序】
通
过上述步骤很容易发现,该算法的基本思想与传统的2-way merge sort如出一辙,时间复杂度也都是O(m+n)。只不过传统的
merge sort中我们要申请额外的目的数组存储排序完成后的数据; 而这里目的数组就是X+Y本身,所以我们要首先交换X和A,将X “腾空”【反复思考,如果没有这么一段额外存储空间,那么保持线性时间复杂度就难了】;另
外传统的merge sort中是将X或Y中的数据赋值给新开辟的目的数组Z,但是这里我们的目的数组中数据不能被破坏,因此只能采用swap操作。
为了有助于理解,我们来看一个例子。假设n=3,且x1
图1 利用辅助数组原地归并排序
下面开始本文的重点,in-place merge sort算法,具体内容参考自TAOCP Vol