归并排序及排序拓展

博客探讨了归并排序的递归和循环实现,强调其稳定性和时间、空间复杂度。同时,总结了排序算法的分类,如内部排序与外部排序,并提及归并排序属于外部排序。此外,讨论了比较排序和非比较排序的概念,举例说明非比较排序的一种应用思路。
摘要由CSDN通过智能技术生成

归并排序

递归代码实现归并

void _MergeDate(int* array,int left,int mid,int right,int* temp)
{
	int index1 = left;
	int index2 = mid;
	int index = left;
	while(index1<mid && index2<right)
	{
		if(array[index1]<=array[index2])
			temp[index++] = array[index1++];
		else
			temp[index++] = array[index2++];
	}
	while(index1<mid)
		temp[index++] = array[index1++];
	while(index2<right)
		temp[index++] = array[index2++];
}
void _MergeSort(int* array,int left,int right,int* temp)
{
	if(right-left>1)
	{
		//求中间位置
		int mid = left+((left-right)>>1);
		//归并左半区间[left,mid)
		_MergeSort(array,left,mid,temp);
		//归并有右区间[mid,right)
		_MergeSort(array,mid,right,temp);
		//归并左[left,mid)右[mid,right)区间-->temp(到temp)
		_MergeDate(array,left,mid,right,temp);
		memcpy(array+left,temp+left,sizeof(array[left])*(right-left));
	}
}
void MergeSort(int* array,int size)
{
	int* temp = (int*)malloc(sizeof(array[0])*size);
	ifNULL == temp)
	{
		assert(0);
		return ;
	}
	_MergeSort(array,0,size,temp);
	free(temp);
}

稳定性:稳定
时间复杂度:O(NlogN)
空间复杂度:O(N);

循环代码实现归并

void MergeDate(int* array,int left,int mid,int right,int* temp)
{
	int index1 = left;
	int index2 = mid;
	int index = left;
	while(index1<mid && index2<right)
	{
		if(array[index1]<=array[index2])
			temp[index++] = array[index1++];
		else
			temp[index++] = array[index2++];
	}
	while(index1<mid)
		temp[index++] = array[index1++];
	while(index2<right)
		temp[index++] = array[index2++];
}
void MergeSort(int* array,int size)
{
	int* temp = (int*)malloc(sizeof(array[0])*size);
	if(NULL == temp)
	{
		assert(0);
		return ;
	}
	int gap = 1;//用gap 标记每个分组的元素数
	while(gap<size)//最少可以分为两个分组
	{
		for(int i = 0;i<size;i+=2*gap)
		{
			int left = i;
			int mid = i+gap;
			int right = i+2*gap;
			if(mid>size)
			mid = size;
			if(right>size)
			right = size;
			//[left,mid)和[mid,right)两个区间的元素归并
			MergeDate(array,left,mid,right,temp);
			//法一:没归并一次拷贝一次
			//memcpy(array+left,temp+left,sizeof(array[left])*(right-left));
		}
		//法二:没归并一趟拷贝一次
		memcpy(array,temp,sizeof(array[0])*size);
		gap*=2;
	}
	free(temp);
}

排序总结
插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序—>内部排序:在排序时需要一次性将所有数据加载到内存中;
归并排序—>外部排序:在排序时不需要一次将所有数据加载到内存中;

比较排序

插入,希尔,选择,堆,冒泡,快速都是比较排序

非比较排序

假设:数据密集的集中在0-9的范围之中;
思考:可以申请一个有10个数的数组,将数组元素置为0;用数组元素记录0-9出现的次数,用数组下标记录数据;

//空间复杂度:O(M),M为maxVaule-minVaule+1
//时间复杂度为O(N);
//稳定性:稳定;
//使用场景:数据集中在某个位置
void CountSort(int* array,int size)
{
	//求最大值,最小值
	int maxVaule = array[0];
	int minVaule = array[0];
	for(int i = 0;i<size;i++)
	{	
		if(array[i]>maxVaule)
		maxVaule = array[i];
		if(array[i]<minVaule)
		minVaule = array[i];
	}

	//申请空间
	int range = maxVaule-minVaule+1;
	int* ArrayCount = (int*)malloc(sizeof(sizeof(int)*range);
	memset(ArrayCount,0,sizeof(int)*range);

	//统计元素出现次数
	for(int i = 0;i<size;i++)
	ArrayCount[array[i]-minVaule]++;
	
	//回收
	int index = 0;
	for(int i = 0;i<range;i++)
	{
		while(ArrayCount[i]--)
		array[index++] = i+minVaule;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值