算法导论 - 归并排序的 C 语言实现

归并排序是 Divide-and-Conquer 编程思想一个简单例子,其逻辑核心主要有以下几点。

(1) 将两个有序数列合并的时间复杂度为 O(n),参见函数 void merge(int *src, int st, int md, int ed, int *sorted);

(2) 数列中只有一个数的时候,数列处于有序状态。

下面是归并排序的示例代码。

#include <stdio.h>
#include <stdlib.h>

void merge(int *src, int st, int md, int ed, int *sorted){
	int i=st, j=md;
	int k=0;
	while(i<md && j<ed){
		if(src[i]<src[j]){
			sorted[k++]=src[i++];
		}else{
			sorted[k++]=src[j++];
		}
	}
	while(i<md){
		sorted[k++]=src[i++];
	}
	while(j<ed){
		sorted[k++]=src[j++];
	}
	i=st;
	k=0;
	while(i<ed){
		src[i++] = sorted[k++];	
	}
}

void merge_sort(int *src, int st, int ed, int *sorted){
	if(st+1<ed){
		int md = (st+ed)/2;
		merge_sort(src, st, md, sorted);
		merge_sort(src, md, ed, sorted);
		merge(src, st, md, ed, sorted);
	}
}

int main(){
	int to_sort[15] = {2, 8, 12, 1, 4, 3, 6, 12, 15, 1, 4, 7, 19, 10, 9};
	int *src = to_sort;
	int i = 0;
	printf("The array before sorting is:\n");
	for(i=0; i<15; ++i){
		printf("%d  ", src[i]);
	}
	printf("\n");

	int *sorted = (int *)malloc(15*sizeof(int));
	merge_sort(src, 0, 15, sorted);

	printf("The array after sorting is:\n");
	for(i=0; i<15; ++i){
		printf("%d  ", sorted[i]);
	}
	printf("\n");
	free(sorted);
	sorted = NULL;
	return 0;
}

使用动态内存实现归并排序时,可以使逻辑更加清晰,但在递归过程中反复申请、释放内存,会频繁产生内存的缺页中断,增加程序执行时间,降低性能。

#include <stdio.h>
#include <stdlib.h>
void merge(int *target, int st, int md, int ed){
	if(st > md || md > ed){
		return;	
	}
	
	int llen = md - st;
	int rlen = ed - md;
	int *left = (int*) malloc(llen*sizeof(int));
	int *right = (int*) malloc(rlen*sizeof(int));

	int i=0, j=0, k=0;

	for(i=0; i<llen; ++i){
		left[i] = target[st+i];
	}
	for(i=0; i<rlen; ++i){
		right[i] = target[md+i];
	}
	
	i=0;
	j=0;

	for(k=st; k<ed; ++k){
		if(i<llen && j<rlen){
			if(left[i]<=right[j]){
				target[k] = left[i];
				++i;
			}else{
				target[k] = right[j];
				++j;
			}
		}else{
			break;
		}
	}

	while(i<llen){
		target[k++] = left[i++];
	}
	while(j<rlen){
		target[k++] = right[j++];
	}

	free(left);
	left = NULL;
	free(right);
	right = NULL;
}

void merge_sort(int *target, int st, int ed){
	if(st>ed || st<0){
		return;
	}
	int md = (st+ed)/2;
	if(st+1<ed){
		merge_sort(target, st, md);
		merge_sort(target, md, ed);
		merge(target, st, md, ed);
	}
}

int main(){
	int to_sort[15] = {2, 8, 12, 1, 4, 3, 6, 12, 15, 1, 4, 7, 19, 10, 9};
	int *target = to_sort;
	int i = 0;
	printf("The array before sorting is:\n");
	for(i=0; i<15; ++i){
		printf("%d  ", target[i]);
	}
	printf("\n");
	merge_sort(target, 0, 15);

	printf("The array after sorting is:\n");
	for(i=0; i<15; ++i){
		printf("%d  ", target[i]);
	}
	printf("\n");
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值