快速排序算法是一种分治排序算法,它将数组划分为两部分,然后分别对这两部分进行排序。它将重排序数组,使之满足一下三个条件:
1,对于某个i,a[i]在最终的位置上
2,a[l]…a[i-1]中的元素都比a[i]小
3,a[i+1] …a[r]中的元素都比a[i]大
通过划分后完成本轮排序,然后递归地处理子文件。
如果数组中有一个或者0个元素,就什么都不做。否则,调用以下算法实现快速排序:
int partition(Itema[],int l,int r)
{
int i=l-1,j=r;
Item v=a[r];
for (;;)
{
while (less(a[++i],v))
{
;
}
while (less(v,a[--j]))
{
if (j==1)
{
break;
}
}
if (i>=j)
{
break;
}
exch(a[i],a[j]);
}
exch(a[i],a[r]);
return i;
}
变量v保存了划分元素a[r],i和j分别是左扫描指针和右扫描指针。划分循环使得i增加j减小,while循环保持一个不变的性质---------i左侧没有元素比v大,j右侧没有元素比v小。一旦两个指针相遇,我们就交换啊a[i]和a[r],,这样v左侧的元素都小于v,v右侧的元素都大于等于v,结束划分过程。
划分是一个不确定的过程,当两个指针相遇,就通过break语句结束。测试j==1用来防止划分元素是文件总的最小元素。
voidquichsort(Item a[],int l,int r)
{
int i;
if (r<=l)
{
return;
}
i=partition(a,l,r);
quichsort(a,l,i-1);
quichsort(a,i+1,r);
}
注:快速排序是一个递归划分过程,我们对一个文件进行划分,划分原则是将一些元素放在它最终的位置上,对数组进行排序使比划分元素小的元素都在划分元素的左边,比划分元素大的元素都在划分元素的右边,然后分别对左右两部分进行递归处理。然后,从数组的左端进行扫描,直到找到一个大于划分元素的元素,同时从数据的右端开始扫描,直到找到一个小于划分元素的元素。使扫描停止的这个两个元素,显然在最终的划分数组中的位置相反,于是交换二者。继续这一过程,我们就可以保证比划分元素小的元素都在划分元素的左边,比划分元素大的元素都在划分元素的右边。
性能特征:
快速排序最坏情况下使用N*N/2次比较
快速排序平均情况下使用2*N*㏒N次比较
快速排序算法是一种不稳定的算法。
算法示意图
A | S | 0 | R | T | I | N | G | E | X | A | M | P | L | E |
A | A | E | E |
|
|
|
| O |
| S |
|
|
| R |
A | A | E |
|
|
|
|
|
|
|
|
|
|
|
|
A | A |
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| L | I | N | G | O | P | M | R | X | T | S |
|
|
|
| L | I | G | M | O | P |
|
|
|
|
|
|
|
|
| G | I | L |
|
|
|
|
|
|
|
|
|
|
|
|
| I | I |
|
|
|
|
|
|
|
|
|
|
|
|
| I |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| N | P | O |
|
|
|
|
|
|
|
|
|
|
|
|
| O | P |
|
|
|
|
|
|
|
|
|
|
|
|
|
| P |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| S | T | X |
|
|
|
|
|
|
|
|
|
|
|
|
| T | X |
|
|
|
|
|
|
|
|
|
|
|
|
| T |
|
A | A | E | E | G | I | L | M | N | O | P | R | D | T | X |