快速排序是运用分治思想的一种性能优良的排序方法,之所以被叫做快速排序是因为它的排序速度非常的快,当然这只是相对某种情况而言的,不过我们仍可以说快速排序是实践当中已知的最快的排序算法.
快速排序的算法是假设有一个数组A[n],首先将这个数组划分为A[1....x]和A[x + 1.......n]两个数组,并且是前一个数组的所有元素都不大于后一个数组的元素.然后再分别对两个数组递归的使用上面的方法排序.因为数组是原地排序的,所以分治中的合并这一步就不需要了.
代码:
#include
<
stdio.h
>
const int MAX = 10 ;
int Partition( int * A, int low, int high)
... {
int temp, i, j, a;
a = A[low];
i = low - 1;
j = high + 1;
while(1)
...{
do
j -= 1;
while(A[j] > a);
do
i += 1;
while(A[i] < a);
if(i < j)
...{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
else
return j;
}
}
void quickSort( int * A, int low, int high)
... {
int position;
if(low < high)
...{
position = Partition(A, low, high);
quickSort(A, low, position);
quickSort(A, position + 1, high);
}
}
int main()
... {
int A[MAX];
int i;
int nums = MAX;
printf("Please input %d numbers: ", nums);
for(i = 0; i < MAX; i++)
scanf("%d", &A[i]);
quickSort(A, 0, MAX - 1);
for(i = 0; i < MAX; i++)
printf("%d ", A[i]);
return 0;
}
const int MAX = 10 ;
int Partition( int * A, int low, int high)
... {
int temp, i, j, a;
a = A[low];
i = low - 1;
j = high + 1;
while(1)
...{
do
j -= 1;
while(A[j] > a);
do
i += 1;
while(A[i] < a);
if(i < j)
...{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
else
return j;
}
}
void quickSort( int * A, int low, int high)
... {
int position;
if(low < high)
...{
position = Partition(A, low, high);
quickSort(A, low, position);
quickSort(A, position + 1, high);
}
}
int main()
... {
int A[MAX];
int i;
int nums = MAX;
printf("Please input %d numbers: ", nums);
for(i = 0; i < MAX; i++)
scanf("%d", &A[i]);
quickSort(A, 0, MAX - 1);
for(i = 0; i < MAX; i++)
printf("%d ", A[i]);
return 0;
}
就像是希尔排序的关键是增量数列一样,快速排序也有影响效率的关键,那就是数组的输入和划分.
假设有一个乱序的文件,致使快速排序每次划分的时候都可以将整个数组平均的分成n / 2,这样的话,我们就可以计算得到运行时间是T(n) = 2T(n / 2) + Θ(n),实际上就是Θ(nlog2n).
如果假设有一个几乎排好序或者是几乎反序的数组,那么运行时候划分情况是相当糟糕的, 几乎每一步都是最不对称的划分,此时的运行时间是Θ(n2) ,而此时的插入排序只需要O(n)的时间.所以快速排序是一个喜欢乱文件的排序算法.
为了解决上面的问题,可以有许多的方法,其中有一种方法就是随机的交换一些数据,消除接近有序的文件所带来的恶果.
代码:
#include
<
stdio.h
>
#include < stdlib.h >
#include < time.h >
const int MAX = 10 ;
int Partition( int * A, int low, int high)
... {
int temp, i, j, a;
a = A[low];
i = low - 1;
j = high + 1;
while(1)
...{
do
j -= 1;
while(A[j] > a);
do
i += 1;
while(A[i] < a);
if(i < j)
...{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
else
return j;
}
}
int randomPartition( int * A, int low, int high)
... {
int i, temp;
srand(time(NULL));
i = rand() % (high - low + 1) + low;//rand是随机函数
temp = A[low];
A[low] = A[i];
A[i] = temp;
return Partition(A, low, high);
}
void quickSort( int * A, int low, int high)
... {
int position;
if(low < high)
...{
position = randomPartition(A, low, high);
quickSort(A, low, position);
quickSort(A, position + 1, high);
}
}
int main()
... {
int A[MAX];
int i;
int nums = MAX;
printf("Please input %d numbers: ", nums);
for(i = 0; i < MAX; i++)
scanf("%d", &A[i]);
quickSort(A, 0, MAX - 1);
for(i = 0; i < MAX; i++)
printf("%d ", A[i]);
return 0;
}
#include < stdlib.h >
#include < time.h >
const int MAX = 10 ;
int Partition( int * A, int low, int high)
... {
int temp, i, j, a;
a = A[low];
i = low - 1;
j = high + 1;
while(1)
...{
do
j -= 1;
while(A[j] > a);
do
i += 1;
while(A[i] < a);
if(i < j)
...{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
else
return j;
}
}
int randomPartition( int * A, int low, int high)
... {
int i, temp;
srand(time(NULL));
i = rand() % (high - low + 1) + low;//rand是随机函数
temp = A[low];
A[low] = A[i];
A[i] = temp;
return Partition(A, low, high);
}
void quickSort( int * A, int low, int high)
... {
int position;
if(low < high)
...{
position = randomPartition(A, low, high);
quickSort(A, low, position);
quickSort(A, position + 1, high);
}
}
int main()
... {
int A[MAX];
int i;
int nums = MAX;
printf("Please input %d numbers: ", nums);
for(i = 0; i < MAX; i++)
scanf("%d", &A[i]);
quickSort(A, 0, MAX - 1);
for(i = 0; i < MAX; i++)
printf("%d ", A[i]);
return 0;
}
按照上面的方法写出的程序在最坏的情况下运行时间仍是Θ(n2),但是这种情况发生的概率已经很小了,对于这样一个算法的平均的运行时间,<<算法导论>>上给出了精确的证明,既是O(nlog2n),