这是一个实际中常用的算法,虽然最差情况的复杂度是O(n^2),但是平均复杂度是O(nlgn)。
且是in place的。
/*
* =====================================================================================
*
* Filename: quick_sort.c
*
* Description:
*
* Version: 1.0
* Created: 10/12/2010 09:54:21 AM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Company:
*
* =====================================================================================
*/
#include <stdio.h>
int A[10] ={1, 4, 19, 234, 2, 98, 5, 76, 0, 87};
// {1, 3, 6, 9, 8, 87, 15, 4, 7, 5};
/*
* A O(n) procedure to partition the array
*/
int Partition(int* A, int p, int r)
{
int x, i, j;
int tmp;
x = A[r];
i = p -1;
for (j = p; j < r; j++)
{
if (A[j] <= x)
{
i++;
tmp = A[j];
A[j] = A[i];
A[i] = tmp;
}
}
A[r] = A[i+1];
A[i+1] = x;
return (i+1);
}
int Random_Partition(int* A, int p, int r)
{
int x, i, j;
int tmp, mid;
mid = (p+r)/2;
tmp = A[r]; A[r] = A[mid]; A[mid] = tmp;
x = A[r];
i = p -1;
for (j = p; j < r; j++)
{
if (A[j] <= x)
{
i++;
tmp = A[j];
A[j] = A[i];
A[i] = tmp;
}
}
A[r] = A[i+1];
A[i+1] = x;
printf("partition is %d/n", i+1);
return (i+1);
}
/*
* A in place sorting algorithm with
* average run time of O(nlgn)
*/
void QuickSort(int* A, int p, int r)
{
int q;
if (p < r)
{
// q = Partition(A, p, r);
q = Random_Partition(A, p, r);
QuickSort(A, p, q-1);
QuickSort(A, q+1, r);
}
}
/*
* QuickSelect
* A average O(n) algorithm to select the kth element
* in array
*/
void QuickSelect(int* A, int p, int r, int k)
{
int q;
if (p < r)
{
q = Random_Partition(A, p, r);
if (q == k)
return;
if (q < k)
QuickSelect(A, q+1, r, k);
else
QuickSelect(A, p, q-1, k);
}
}
int main()
{
int i;
// QuickSort(A, 0, 9);
//
QuickSelect(A, 0,9,3);
for(i=0; i<10; i++)
{
printf("%d,", A[i]);
}
printf("/n");
return 0;
}
另外一个版本的,我觉得我写错了,但是结果尽然是对的。
对是个巧合,第一次写这个代码的时候,我以为每次partition后是要改写k这个数字的。
后来想起来,每次partition后返回值是一个全过程不变的值。 不应该改变。
#include<iostream>
using namespace std;
int a[5000001] = {1, 4, 19, 234, 2, 98, 5, 76, 0, 87};
int n,k;
int partition(int begin,int end)
{
int x, i, j;
int tmp;
int mid = (begin+end)/2;
x=a[mid];
a[mid] = a[end]; a[end] = x;
i = begin - 1;
for (j = begin; j < end; j++)
{
if (a[j] <= x)
{
i++;
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
a[end] = a[i+1];
a[i+1] = x;
cout << "patition is " << i+1 << endl;
return (i+1);
}
void quick_sort(int s,int t)
{
int i;
if(s<t)
{
i=partition(s,t);
quick_sort(s,i-1);
quick_sort(i+1,t);
}
}
void quick_search_k(int s,int t,int k)
{
int i;
if(s<t)
{
i=partition(s,t);
if(i==k)
return;
else if(i<k)
quick_search_k(i+1,t,k-i-2);
else
quick_search_k(s,i-1,k);
}
}
int main()
{
int t;
// while(scanf("%d%d",&n,&k)!=EOF)
// {
// for(int i=0;i<n;i++)
// scanf("%d",&a[i]);
// quick_sort(0,n-1,k-1);
// cout<<a[k-1]<<endl;
// }
quick_search_k(0, 9, 3);
for (t=0; t<10; t++)
{
cout << a[t] << " " << endl;
}
cout<<a[3]<<endl;
}