定义:
在快速排序算法中,使用了分治策略,将要排序的序列分成两个子序列,然后递归地对子序列进行排序,直到整个序列排序完毕。
步骤:
1.在序列中选择一个关键元素作为轴;
2.对序列进行重新排序,将比轴小的元素移到轴的前边,比轴大的元素移动到轴的后面。在进行划分之后,轴便在它最终的位置上;
3.递归地对两个子序列进行重新排序:含有较小元素的子序列和含有较大元素的子序列。
从上图可以看出,每次的比较选取的key元素为序列最后的元素。
C语言实现:
#include <stdio.h>
#include <stdlib.h>
void swap(int *x,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int choose_pivot(int i,int j )
{
return((i+j) /2);
}
void quicksort(int list[],int m,int n)
{
int key,i,j,k;
if( m < n)
{
k = choose_pivot(m,n);
swap(&list[m],&list[k]);
key = list[m];
i = m+1;
j = n;
while(i <= j)
{
while((i <= n) && (list[i] <= key))
i++;
while((j >= m) && (list[j] > key))
j--;
if( i < j)
swap(&list[i],&list[j]);
}
// 交换两个元素的位置
swap(&list[m],&list[j]);
// 递归地对较小的数据序列进行排序
quicksort(list,m,j-1);
quicksort(list,j+1,n);
}
}
void printlist(int list[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\t",list[i]);
}
void main()
{
const int MAX_ELEMENTS = 10;
int list[MAX_ELEMENTS];
int i = 0;
// 产生填充序列的随机数
for(i = 0; i < MAX_ELEMENTS; i++ ){
list[i] = rand();
}
printf("进行排序之前的序列:\n");
printlist(list,MAX_ELEMENTS);
// sort the list using quicksort
quicksort(list,0,MAX_ELEMENTS-1);
// print the result
printf("使用快速排序算法进行排序之后的序列:\n");
printlist(list,MAX_ELEMENTS);
}
总结:
快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,工需要划分K-1次关键字的比较。
最坏的情况:每次划分选取的基准(关键元素)都是当前无序区间中最小(或者最大)的记录,划分的结果就是基准左边的子区间为空(或右边的子区间为空),而划分所得的另外一个非空子区间中记录的数目,仅仅比划分前的无序区中记录的个数少一个。时间复杂度为:O(n*n)
最好的情况:每次划分所取的基准都是当前无序区的“中值”记录,划分的结果是基准的左右两个无序区的长度大致相等。时间复杂度为:O(n*lgn)
尽管快速排序的最坏时间复杂度为O(n*n),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快的,平均时间复杂度为O(n*lgn)。