思路:
快速排序也是一种分治的递归思想。通过选取一个枢纽元,将数组分成两个子数组,一个子数组大于该枢纽元,另一个子数组小于该枢纽元,然后对这两个子数组递归使用该方法排序,当一个数组中的元素个数很小时,可以使用插入排序对小数组中的元素排序。
基本步骤:
- 如果数组中的元素个数是0或1,则返回;
- 在数组中选取一个元素,作为枢纽元;
- 将数组中除了枢纽元外的元素,分为两部分,一部分大于该枢纽元,一部分小于该枢纽元;
- 将划分后的两个部分继续使用该方法排序,直到所有元素均已排序。
时间复杂度:
最好: ;平均:
;最坏:
程序:
int swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
int median3(int array[],int left,int right)
{
int tmp;
int center=(left+right)/2;
if(array[left]>array[center]) //这里用选择排序给数组开始,中间,和结尾三个位置的元素排序
{
tmp=array[left];
array[left]=array[center];
array[center]=tmp;
}
if(array[left]>array[right])
{
tmp=array[left];
array[left]=array[right];
array[right]=tmp;
}
if(array[center]>array[right])
{
tmp=array[center];
array[center]=array[right];
array[right]=tmp;
}
swap(&array[center],&array[right-1]);
return array[right-1];
}
void insert_sort(int array[],int array_size)
{
int i,j,tmp;
for(i=1;i<array_size;i++)
{
tmp=array[i];
for(j=i;j>0&&array[j-1]>tmp;j--)
array[j]=array[j-1];
array[j]=tmp;
}
}
void quick_sort_recursion(int array[],int left,int right)
{
int middle, i,j;
if((right-left)<2)
return;
if((right-left)>5) //由于数组元素太少使用快速排序效率很低,所以元素大于6个使用快速排序,元素小于6个使用插入排序
{
i=left;
j=right-1;
middle=median3(array,left,right);
while(1)
{
while(middle>array[++i])
{}
while(middle<array[--j])
{}
if(i<j)
swap(&array[i],&array[j]);
else
break;
}
swap(&array[i],&array[right-1]);
quick_sort_recursion(array,left,i-1);
quick_sort_recursion(array,i+1,right);
}
else
insert_sort(array+left,right-left+1);
}
void quick_sort(int array[],int array_size)
{
quick_sort_recursion(array,0,array_size-1);
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
int array[]={100,96,88,75,63,52,41,36,28,96,19,6,0,-19,-105,28,52,52,52};
int array_size=sizeof(array)/sizeof(int);
printf("Original array:\n");
for(i=0;i<array_size;i++)
printf(" %d, ",array[i]);
printf("\n");
quick_sort(array,array_size);
printf("Sorted array:\n");
for(i=0;i<array_size;i++)
printf(" %d, ",array[i]);
printf("\n");
return 0;
}