【数据结构】C语言实现排序算法------快速排序

快速排序:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的数据比另一部分记录的关键字小,则分别可对这两部分数据进行继续排序,以达到整个序列有序。

快速排序有三个版本:

1.hoare版本

示图:

在这里插入图片描述

代码:hoare版本

int _QuickSort_1(int *arr, int left, int right)//hoare版本
{
	int tmp = arr[left];//基准值
	while (left < right)
	{
		while (left < right && tmp < arr[right])
			right--;
		Swap(&arr[left], &arr[right]);
		while (left < right && tmp >= arr[left])
			left++;
		Swap(&arr[left],&arr[right]);
	}
	return left;
}

void QuickSort(int *arr, int left, int right)
{
	if (left >= right)
		return;
	int end = _QuickSort_1(arr, left, right - 1);
	QuickSort(arr, left, end);
	QuickSort(arr, end + 1, right);
}

2.挖坑法

排序需要两个操作:

  1. 数据比较
  2. 数据交换

挖坑法是通过减少对数据的交换来达到排序。

代码:挖坑法

int _QuickSort_2(int *arr, int left, int right)//挖坑法
{
	int tmp = arr[left];
	while (left < right)
	{
		while (left < right && tmp < arr[right])
			right--;
		arr[left] = arr[right];
		while (left < right && tmp >= arr[left])
			left++;
		arr[right] = arr[left];
	}
	arr[left] = tmp;//tmp的值,一定要放到最后的空间中
	return left;
}

void QuickSort(int *arr, int left, int right)
{
	if (left >= right)
		return;
	int end = _QuickSort_2(arr, left, right - 1);
	QuickSort(arr, left, end);
	QuickSort(arr, end + 1, right);
}

3.双指针法

通过设置快慢指针的方法来达到排序。

算法步骤::

  1. 设置两个指针pos,forward
  2. forward处值小于基准值,pos++,如果pos≠forward,将两者值交换
  3. foward处值大于基准值,pos不动
  4. 最后pos的值和起始位置值交换,返回pos

代码:双指针法

int _QuickSort_3(int *arr, int left, int right)//双指针法
{
	int tmp = arr[left];//基准值
	int pos = left;
	int forward = left;
	for (forward; forward <= right; ++forward)
	{
		if (arr[forward] < tmp)//小于是做升序,大于做降序
		{
			pos++;
			if (pos != forward)
			{
				Swap(&arr[forward], &arr[pos]);
			}
		}
	}
	Swap(&arr[left], &arr[pos]);
	return pos;
}

void QuickSort(int *arr, int left, int right)
{
	if (left >= right)
		return;
	int end = _QuickSort_3(arr, left, right - 1);
	QuickSort(arr, left, end);
	QuickSort(arr, end + 1, right);
}

4.优化方法

快速排序有一些待改进的地方。

若:起始位置为最大或者最小时,排序的效率并不高,故采用三路折中法对算法进行改进。

分别对:起始位置,中间位置,末尾位置进行比较,选取中间值进行排序。

int GetMidValue(int *arr, int left, int right)//三路折中法
{
	int mid = (left + right) / 2;
	if (arr[mid] > arr[left] && arr[mid] < arr[right])
		return mid;
	else if (arr[mid] < arr[left] && arr[left] < arr[right])
		return left;
	return right;
}

数据长度在5~25之间的时候,算法效率没有直接插入快(出自殷人昆教授的数据结构教材)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值