您的位置:首页 > 其它

最容易理解的快速排序方法和程序

2011-09-16 15:06 423 查看
希尔排序相当于直接插入排序的升级,它们同属于插入排序类,堆排序相当于简单选择排序的升级,它们同属于选择排序类。而快速排序其实就是我们前面认为最慢的冒泡排序的升级,它们都属于交换排序类。即它也是通过不断的比较和移动交换来实现排序的,只不过它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数和移动交换次数。

快速排序(Quick Sort)的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

以前总觉得快速排序挺晦涩的,大学的时候考试还是得死记硬背呢!今天看到了伍迷老师对各种排序算法的讲解,觉得思路清晰,十分易懂,以后应该不会忘记的干干净净了。放在这里为学习备份~~

下面看这个思想十分容易接受的程序:

#include <stdio.h>

void swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}

/* 交换a中子表的记录,使枢轴记录到位,并返回其所在位置 */
/* 此时在它之前(后)的记录均不大(小)于它。 */
int partition(int a[],int low,int high)
{
int pivotKey;
pivotKey = a[low];//用子表的第一个记录作枢轴记录

while(low < high)// 从表的两端交替地向中间扫描
{
while(low < high && a[high] >= pivotKey)
high--;
swap(&a[low],&a[high]);//将比枢轴记录小的记录交换到低端
while(low < high && a[low] <= pivotKey)
low++;
swap(&a[low],&a[high]);//将比枢轴记录大的记录交换到高端
}
return low;//返回枢轴所在位置
}

void QSort(int a[],int low,int high)
{
int pivot;
if(low < high)
{
pivot = partition(a,low,high);//将a数组一分为二,且返回枢值的位置
QSort(a,low,pivot-1);//对低子表递归
QSort(a,pivot+1,high);//对高子表递归
}
}

//快速排序
void QuickSort(int a[],int n)
{
QSort(a,0,n-1);//由于需要递归调用,因此我们外封装了一个函数
}

void main()
{
int i;
int a[8] = {5,4,1,3,9,5,8,2};
QuickSort(a,8);
for(i=0;i<8;i++)
{
printf("%d ",a[i]);
}
printf("\n");
}


因为在现实中,待排序的系列极有可能是基本有序的,此时,总是固定选取第一个关键字(其实无论是固定选取哪一个位置的关键字)作为首个枢轴就变成了极为不合理的作法。

改进,于是就有了三数取中(median-of-three)法即取三个关键字先进行排序,将中间数作为枢轴,一般是取左端、右端和中间三个数,也可以随机选取。这样至少这个中间数一定不会是最小或者最大的数,从概率来说,取三个数均为最小或最大数的可能性是微乎其微的,因此中间数位于较为中间的值的可能性就大大提高了。由于整个序列是无序状态,随机选取三个数和从左中右端取三个数其实是一回事,而且随机数生成器本身还会带来时间上的开销,因此随机生成不予考虑。

我们来看看取左端、右端和中间三个数的实现代码,在Partition函数代码的第3行与第4行之间增加这样一段代码。

int pivotkey;

int m = low + (high - low)  /* 计算数组中间的元素的下标 */
if (a[low]>a[high])
swap(&a[low],&a[high]);    /* 交换左端与右端数据,保证左端较小 */
if (a[m]>a[high])
swap(&a[high],&a[m]);    /* 交换中间与右端数据,保证中间较小 */
if (a[m]>a[low])
swap(&a[m],&a[low]);    /* 交换中间与左端数据,保证左端较小 */

/* 此时L.r[low]已经为整个序列左中右三个关键字的中间值。*/
pivotkey=L->r[low];    /* 用子表的第一个记录作枢轴记录 */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: