快速排序算法介绍

划分问题:把数组的各个元素重排后分成左右两个部分,使得左边任意元素都小于或等于右边任意元素。

递归求解:把左右两部分分别排序。

快速排序代码

#include <iostream>
using namespace std;
void swap(int & a,int & b)
{//交换变量a,b值
int tmp=a;
a=b;
b=tmp;
}
void QuickSort(int a[],int s,int e)
{
if(s>=e)
return ;
int k=a[s];
int i=s,j=e;
while(i!=j)
{
while(j>i&&a[j]>=k) --j;
swap(a[i],a[j]);
while(i<j&&a[i]<=k) ++i;
swap(a[i],a[j]);
}//处理完后,a[i]=k
QuickSort(a,s,i-1);
QuickSort(a,i+1,e);
}
int a[]={93,27,30,2,8,12,2,8,30,89};
int main ()
{
int size=sizeof(a)/sizeof(int);
QuickSort(a,0,size-1);
for(int i=0;i<size;++i)
{
cout<<a[i]<<",";
}
cout<<endl;
return 0;
}

快速选择问题

输入n个整数和一个正整数k(1<=k<=n),输出这些整数从小到大排序后的第k个,n<=10​7​。

分析

假设在快速排序的“划分”结束后,数组A[p……r]被分成了A[p……q]和A[q+1……r],则可以根据左边的元素个数q-p+1和k的大小关系只在左边或者只在右边递归求解。

代码

#include <iostream>
#include <algorithm>

using namespace std;

int qsort(int *a, int left, int right, int k) {//快速排序算法
if (left > right) return 0; //递归边界
int centerV = a[left + (right - left) / 2]; //取标兵值

int i = left, j = right;
while (i <= j) {
while (i <= j) {//从左往右扫描大于标兵值的元素,放在标兵值右侧
if (a[i] >= centerV) break;
i++;
}
while (j >= i) {//从右往左扫描小于标兵值的元素,放在标兵值左侧
if (a[j] <= centerV) break;
j--;
}
if (i > j) break; //退出条件
swap(a[i], a[j]);
i++;
j--;
}
if (k - 1 <= i) //递归求左半解
return qsort(a, left, j, k);
else if (k - 1 > i + 1) //递归求右半解
return qsort(a, i, right, k);
else
return a[k - 1];
}

int QuickSort(int *pInt, int n, int k) {
return qsort(pInt, 0, n - 1, k);
}

int main() {
int a[10] = {1, 2, 3, 4, 9, 33, 12, 8, 9, 10};
int n = 10, k = 9;
cout << "Before sorting: ";
for (int i = 0; i < n; ++i) {
cout << a[i] << ' ';
}
cout << endl;
int ans = QuickSort(a, n, k);
cout << "After sorting: ";
for (int i = 0; i < n; ++i) {
cout << a[i] << ' ';
}
cout << endl;
cout << "Number " << k << " is: " << ans << endl;
return 0;
}