1. 递归实现归并排序的伪算法
|
|
2. 时间复杂度及稳定性分析
b[i] <= c[i]
时是稳定的;b[i] < c[i]
时是不稳定的;
因此,归并排序是稳定的。
3. c语言实现
merge函数(归并两个递增子序列)
void merge(int a[], int p, int q, int r){
int n1 = q - p + 1;
int n2 = r - q;
int *b = (int*)malloc((n1+1)*sizeof(int));
int *c = (int*)malloc((n2+1)*sizeof(int));
memcpy(b, a + p, n1*sizeof(int));
memcpy(c, a + q + 1, n2*sizeof(int));
b[n1] = INT32_MAX; // 0x7fffffff
c[n2] = INT32_MAX;
int i = 0, j = 0;
for(int k = p; k <= r; k++){
if(b[i] <= c[j]){
a[k] = b[i];
i++;
}
else{
a[k] = c[j];
j++;
}
}
free(b);
free(c);
}
merge_sort(递归,自顶向下)
void merge_sort(int a[], int p, int r){
if(p < r){
int q = (p + r) / 2; // int q = (p + r) >> 1 使用移位更好
merge_sort(a, p, q);
merge_sort(a, q+1, r);
merge(a, p, q, r);
}
}
merge_sort(bottomUp,自底向上)
![]() |
![]() |
![]() |
void bottomUp_sort(int a[],int n)
{
int t = 1;
while(t < n){
int s = t, i = 0;
t = 2*s;
while(i + t <= n){
merge(a, i, i+s-1, i+t-1);
i += t;
}
if(i + s < n){
merge(a, i, i+s-1, n-1);
}
}
}
4. 假设有n个有序子序列且每个序列的大小已知,如何合并为一个有序序列?
首先肯定要把多个序列合并,根据大小size[]获得每个子序列的起始位置pos[]。
pos[0] = 0;
for(int i = 1; i < n; i++){
pos[i] = pos[i - 1] + size[i - 1];
memcpy(a + pos[i], ... , size[i]);
}
然后使用归并排序。参数中的p和r均表示子序列序号。pos[]和size[]两个数组也可以设为全局变量从而避免写入形参中。
void merge_sort(int a[], int p, int r, int pos[], int size[]){
if(p < r){
int q = (p + r) / 2; // int q = (p + r) >> 1 使用移位更好
merge_sort(a, p, q, pos, size);
merge_sort(a, q+1, r, pos, size);
merge(a, pos[p], pos[q] + size[q] - 1, pos[r] + size[r] - 1);
}
}