归并排序(Merge Sort)

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);
    }
}
5. merge函数另一种伪代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值