问题描述:数组a[n],a[0]~a[m]和a[m+1]~a[n-1]两个子数组分别是有序的,其中m<n-1。要求在O(n)的时间复杂度和O(1)的空间复杂度内使整个数组有序。
我的思路:由于要求使用O(1)的空间,所以只能依靠交换来实现排序。在数组中央开辟临时数组,存放因交换而产生的数据,这个临时数组也是有序的,举例如下:
n = 9, m = 3
3 4 10 12 5 6 8 9 11
a[0]与a[4]比较,无需交换,继续
a[1]与a[4]比较,无需交换,继续
a[2]与a[4]比较,需要交换:
3,4,5,12,10,6,8,9,11
此时临时数组为a[4]这一个元素,我们继续比较
a[3], a[4], a[5]比较,a[3]与a[5]交换,临时数组元素增为两个a[4]与a[5]:
3,4,5,6,10,12,8,9,11
a[4], a[4], a[6]比较,需要交换,同时临时数组指向a[6],且只有一个a[6]元素:
3,4,5,6,8,12,10,9,11
a[5], a[6], a[7]比较,a[5]与a[7]交换,临时数组此时为a[6]和a[7]:
3,4,5,6,8,9,10,12,11
a[6], a[6], a[8]比较,无需交换,可以认为此时临时数组清空
a[7], a[8]比较,交换
3,4,5,6,8,9,10,11,12
排序结束
程序如下(未验证):
#include<iostream>
using namespace std;
void swap(int& value1, int& value2);
int compare(int value1, int index1, int value2, int index2);
int compare(int value1, int index1, int value2, int index2, int value3, int index3);
int main() {
int *a, n, m, i;
cin>>n>>m;
a = new int[n];
for (i=0; i<n; i++) {
cin>>a[i];
}
int pre_start=0, pre_end=m-1, tmp_start=-1, tmp_end=-1, suf_start=m, suf_end=n-1;
int tmp_index=0, tmp_value=0, min_index=-1;
bool swap_need=0;
while (suf_start<suf_end) {
if (pre_start == tmp_start || tmp_start==-1) {
min_index = compare(a[pre_start], pre_start, a[suf_start], suf_start);
if (min_index != pre_start) {
swap(a[pre_start], a[suf_start]);
tmp_start = tmp_end = suf_start;
pre_start ++;
suf_start ++;
} else {
pre_start ++;
}
} else {
min_index = compare(a[pre_start], pre_start, a[tmp_start], tmp_start, a[suf_start], suf_start);
if (min_index == pre_start) {
pre_start ++;
} else if (min_index == tmp_start) {
swap(a[pre_start], a[tmp_start]);
pre_start ++;
} else if (min_index == suf_start) {
swap(a[pre_start], a[suf_start]);
pre_start ++;
suf_start ++;
}
}
}
return 0;
}
void swap(int& value1, int& value2) {
int tmp = value1;
value1 = value2;
value2 = tmp;
}
int compare(int value1, int index1, int value2, int index2) {
if (value1>value2) return index2;
else return index1;
}
int compare(int value1, int index1, int value2, int index2, int value3, int index3) {
if (value1>value2) {
if (value2>value3) return index3;
else return index2;
} else {
if (value1>value3) return index3;
else return index1;
}
}