快速排序与归并排序递归与非递归c语言实现详解

快速排序

         快排基本逻辑:

首先我们来用挖坑法实现:首先确定一个“坑”,分左右两部分,确定首与尾值以及“坑”所对应的值,按升序方式则为右部分选择小值与“坑”对应的值比较,左边选大值与“坑”比较。从左或右比较选值根据”坑“的位置在左还是右再比较       左边则从右边选,右边则从左边选。

  •  接下来我们就用代码来实现
  • 下述代码为避免首项就为最小值问题而增加消耗而加入了Getmid函数获取三项中的中间值
void Quict_sort(int* dat, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int index=Getmid(dat, left, right);
	Swap(dat[left], dat[index]);
	int begin = left;
	int end = right;
	int pivot = begin;
	int core = dat[pivot];
	while (begin < end)
	{
		while (begin<end && dat[end]>core)//小值
		{
			end--;
		}
		dat[pivot] = dat[end];
		pivot = end;
		while (begin < end && dat[begin] < core)//大值
		{
			begin++;
		}
		dat[pivot] = dat[begin];
		pivot = begin;
	}
	pivot = begin;
	dat[pivot] = core;
	Quict_sort(dat, left, pivot - 1);//递归左半部分
	Quict_sort(dat, pivot + 1, right);//递归右半部分1
}

 三位取中增加效率

int Gitmid(int* dat, int left, int right)
{
	assert(dat);
	int mid = (left + right) >> 1;
	if (dat[left] < dat[mid])
	{
		if (dat[mid] < dat[right])
		{
			return mid;
		}
		else if (dat[left] > dat[right])
		{
			return left;
		}
		else
			return right;
	}
	else
	{
		if (dat[mid] > dat[right])
		{
			return mid;
		}
		else if (dat[left] < dat[right])
		{
			return left;
		}
		else
			return right;
	}
}

 下述类似于挖坑法,通过前后比较得出key应该放的位置

//左右指针法
void Quict_sort(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int index=Gitmid(a, left, right);
	Swap(a[left], a[index]);
	int key = left;
	int pre = left;  int cur = left + 1;
	while (cur <= right)
	{
		if (a[cur] < a[key] && ++pre!=cur)
		{
			Swap(a[pre], a[cur]);
		}
		++cur;
	}
	Swap(a[key], a[pre]);
	int pivot = pre;
	Quict_sort(a, left, pivot - 1);//递归左半部分
	Quict_sort(a, pivot + 1, right);//递归右半部分
}

 

  •  上述该左右指针法也类似与挖坑法,也为比较排序寻找该key在有序数据中的中间位置而通过控制两下标加加选小值交换而达到目的

快排的非递归 

  • 我们已然清楚了快排的具体实现,而非递归则是将递归部分利用栈存储下标,通过出栈入栈而达到递归的效果,思路于上述类似。

归并排序 

基本思路:只需假设有序后分治递归,依次比较即可

void MergSort_(int* dat, int left, int right, int* tmp)
{
	if (left >= right)
	{
		return;
	}
	int mid = (left + right) >> 1;
	//假设有序,进行分治递归
	MergSort_(dat, left, mid , tmp);
	MergSort_(dat, mid + 1, right, tmp);
	//定义变量
	int begin1 = left; int end1 = mid;
	int begin2 = mid + 1; int end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (dat[begin1] < dat[begin2])
		{
			tmp[index++] = dat[begin1++];
		}
		else
		{
			tmp[index++] = dat[begin2++];
		}
	}
	while (begin1 <= end1)//考虑到比较完可能有剩余值直接放入数组即可
	{
		tmp[index++] = dat[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[index++] = dat[begin2++];
	}
	for (int i = left; i <= right; i++)
	{
		dat[i] = tmp[i];
	}
}

void MergeSort(int* dat, int num)
{
	int* tmp = (int*)malloc(num * sizeof(int));
	MergSort(dat, 0, num - 1, tmp);
	free(tmp);
}

上述则为归并排序 

 归并非递归

  • 类似于希尔排序,通过定义一个gap,再通过循环每排完一次,两数直接比较的空隙就翻倍,最终最后一组通过首项与末项比较确定有序。 
void MergeSort(int* dat, int num)
{
	int* tmp = (int*)malloc(num * sizeof(int));
	int gap = 1;
	while (gap < num)
	{
		for (int i = 0; i < num; i += 2 * gap)
		{
			int begin1 = i; int end1 = i + gap - 1;
			int begin2 = i + gap; int end2 = i + 2 * gap - 1;
			int index = i;
			if (begin2 >= num)//防止越界
				break;
			if (end2 >= num)//防止剩一个数时越界
				end2 = num - 1;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (dat[begin1] < dat[begin2])
				{
					tmp[index++] = dat[begin1++];
				}
				else
				{
					tmp[index++] = dat[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[index++] = dat[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[index++] = dat[begin2++];
			}
			for (int i = 0; i <= end2; i++)
			{
				dat[i] = tmp[i];
			}
		}
		gap *= 2;//每次间隙翻两倍
	}
	free(tmp);
}

 以上就是较重要的两大排序,请多多支持,点赞+转发,感激不尽

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒风凋零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值