用快排找出第K大元素

一定要随机地选择标定元素
因为在 __quickSort函数中只处理了l==r的情况,
还有 l>r的情况(比如第一个元素就是最小值,此时partition返回的值是l,将数组分为两部分(l,l-1)和(l+1,r))
如果随机地挑选标定元素,出现这种情况的概率就会非常小

本代码可以满足绝大多数情况
   int arr[8] = { 8,7,1,2,0,3,5,4 };

   
#include
#include
#include
#include
#include "SortTestHelper.h"

using namespace std;

//返回一个partition的值
template
int  __partition(T arr[], int l, int r)
{
	//优化一:随机地选择标定元素(可以让快排在近乎有序的顺序下,加快速度)
	swap(arr[l], arr[rand() % (r - l - 1) + l]);
	T v = arr[l];

	//arr[l+1.....i]==v
	int i = l + 1, j = r;

	while (true)
	{
		while (i <= r&&arr[i] > v) i++;
		while (j >= l + 1 && arr[j]  j) break;
		swap(arr[i], arr[j]);
		i++;
		j--;
	}
	swap(arr[l], arr[j]);
	return j;
}

//对arr[l......r]进行快速排序
template
T __quickSort(T arr[], int l, int r,int k)
{
	if (l == r)
		return arr[l];

	
	int p = __partition(arr, l, r);
	if (p == k)
		return arr[p];
	else if(p>k)
	    __quickSort(arr, l, p - 1,k);
	else 
	    __quickSort(arr, p + 1, r,k);
}



template
T quickSort(T arr[], int n,int k)
{
	srand(time(NULL));
	return __quickSort(arr, 0, n - 1,k-1);
}


int main()
{
	int n = 8;
	int arr[8] = { 8,7,1,2,0,3,5,4 };
	SortTestHelper::printArray(arr, n);
	cout << quickSort(arr, 8, 3)<< endl;
	return 0;
}

你可能感兴趣的:(c++)