快速排序

快速排序是一种平均时间复杂度为 O ( N l o g N ) O(NlogN) O(NlogN)
首先解决一下问题:对于数组 A [ 0 ] , A [ 1 ] , . . . A [ n − 1 ] A[0],A[1],...A[n-1] A[0],A[1],...A[n1],选择其中的一个数作为基准(这里选择A[0]),调整数组元素的位置,使得A[0]左边的元素都不超过A[0],右边的元素都大于A[0]。例如对于原序列{5,3,2,6,7,8,1}
元素切分

实现以上元素调整,有一种很方便的实现方法:two pointer

  • 将A[0]保存在一个临时变量temp中,令下标left,right分别指向数组序列的首位元素
  • 只要right指向的元素比temp大,就将right不断左移,当某个时刻
    A[right] <= temp时,就需要将这个位置的元素移到前面的left位置
  • 只要left指向的元素不比temp大,就将left不断右移,当某个时刻A[left] >= temp时,就需要将这个元素移动到后面的right位置。
  • 重复以上两步,直到left,right相遇,把temp放在相遇点。
    img
int partition(vector<int>&arr,int left,int right)
{
	int temp = arr[left];
	while (left < right)
	{
		while (left < right && arr[right] > temp) {
			--right;
		}
		arr[left] = arr[right];
		while (left < right && arr[left] <= temp) {
			++left;
		}
		arr[right] = arr[left];
	}
	
	arr[left] = temp;
	return left;

}

void quickSort(vector<int>&arr, int start, int end)
{
	if (start < end)
	{
		int pos = partition(arr, start, end);
		quickSort(arr, start, pos - 1);
		quickSort(arr, pos + 1, end);
	}
}

因为以上选择的基准是始终数数据段的第一个元素,为了防止最坏的的情况出现,一般随机选择这个基准,修改如下:

int partition(vector<int>&arr,int left,int right)
{
	int p = rand() % (right - left + 1) + left;
	swap(arr[p], arr[left]);
	int temp = arr[left];
	while (left < right)
	{
		while (left < right && arr[right] > temp) {
			--right;
		}
		arr[left] = arr[right];
		while (left < right && arr[left] <= temp) {
			++left;
		}
		arr[right] = arr[left];
	}
	
	arr[left] = temp;
	return left;
}

测试:

int main()
{
	vector<int>arr = { 35,18,16,72,24,65,12,88,46,28,55 };
	quickSort(arr, 0, arr.size()-1);
	for (int i = 0; i < arr.size(); i++)
	{
		cout << arr[i] << "\t";
	}
	cout << endl;
	system("pause");
	return 0;
}

img

快排应用

  1. 数组的第K大元素
  2. 最小k个数
  3. 奇偶排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值