在这么多的排序算法中,个人认为只有快速排序算法才能算得上高手啦。如果毕业工作后,你的老板叫你写一个算法的话,如果没有快速排序算法的话,我建议你还是偷偷的吧快速排序算法敲进电脑,这样才不会被大家取笑。
快速排序的基本思想:
通过一趟排序将待排序的记录分割成独立的两部分,其中一部分的关键字均比另一部分的关键字小,则可分别对这两部分的记录继续进行排序(这里用的是递归的思想),以达到整个序列有序的目的。
快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。其实快速排序是基于一种叫做“二分”的思想。我们后面还会遇到“二分”思想,到时候再聊。
献上代码,如下:
#include <stdio.h>
#define MAXSIZE 100
void print(int *p,int len)
{
int i;
for(i=0;i<len;i++)
printf("%d ",p[i]);
printf("\n");
}
int partition(int *p,int len)
{
if(len<=1)
return 1;
int mid=p[0]; //mid作为基准
int left=0;
int right=len-1;
while(left<right)
{
while(p[right]>=mid && left<right)
right--;
p[left]=p[right];
while(p[left]<=mid && left<right)
left++;
p[right]=p[left];
}
p[left]=mid; //最终将基准数归位
return left;
}
void Quick_sort(int *p,int len)
{
int pivot;
if(len<=1)
return;
pivot=partition(p,len);
Quick_sort(p,pivot); //继续处理左边的,这里是一个递归的过程
Quick_sort(p+pivot+1,len-pivot-1); //继续处理右边的,这里是一个递归的过程
}
int main()
{
int len=0,tmp=0;
char string[100];
char *str=string;
int a[MAXSIZE]={0};
printf("请输入要排序的数字\n");
gets(string);
while(*str!='\0')
{
while(*str!=' '&&*str!='\0')
{
a[len]=a[len]*10+*str-'0';
str++;
}
len++;
while(*str==' ')
str++;
}
printf("排序后的结果\n");
Quick_sort(a,len);
print(a,len);
return 0;
}
附:1:快速排序并不是稳定的,这是因为我们无法保证相等的数据会按顺序被扫描到和按顺序存放。
2:快速排序在大多数情况下是适用的,尤其在数据量大的时候性能更加明显。但是在必要的时候,需要考虑下优化以提高其在最坏的情况下的性能。
3:递归思想的适用,使得快速排序算法比较直观自然,容易理解和书写,而非递归算法一般更为难懂,但是性能比递归算法更加优良,以为其省去了大量的函数调用开销。