快速排序算法介绍

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

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

快速排序代码
#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<=107

分析

假设在快速排序的“划分”结束后,数组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;
}