浅谈快速排序

编程入门 行业动态 更新时间:2024-10-22 19:42:46

<a href=https://www.elefans.com/category/jswz/34/1769825.html style=浅谈快速排序"/>

浅谈快速排序

转载请注明出处:

谈起快速排序,大家都不陌生了,学过数据结构的人(除了那些逃课或者上课睡觉的人)都知道它,如果还有人现在不能马上手写出快速排序的算法,那就赶紧过来跟我一起重温一下快速排序的精髓吧!面试可是经常会被问起或当场手写代码的哦!

快速排序最早由图灵奖获得者Tony Hoare设计出来的,该算法被列为20世纪十大算法之一。

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

我们现在直接上代码分析(C语言):

#define MAXSIZE 10
#define STATUS bool
//声明结构体
typedef struct{
int r[MAXSIZE];
int length;
}SqList;//交换函数,下面会用到,在这里先定义
/*交换L中数组r的下标为i和j的值*/
void swap(SqList *L,int i,int j){
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
}/* 对顺序表L作快速排序 */
void QuickSort ( SqList *L)
{Qsort(L,1,L->length);
}

由于需要递归调用,我们外封装了 一个函数,现在来看看Qsort的具体实现。


/* 对顺序表L中的子序列L->r[low] ~ L->r[high]作快速排序,low为当前待排序的序列最小下标值,high为当前待排序的序列最大下标值 */
void Qsort ( SqList *L,int low, int high)
{int pivot;  /* 枢轴值 */if(low < high){pivot = Partition (L,low,high);  /* 将L->[low...high]一分为二,算出枢轴值pivot */Qsort(L,low,pivot-1);  /* 对低子表递归操作 */Qsort(L,pivot+1,high);  /* 对高子表递归操作 */
}

这一段的核心是“pivot = Partition (L,low,high);” ,假设我们要对数组{50,10,90,30,70,40,80,60,20}进行排序,Partition函数要做的就是先选取当中的一个关键字,比如选择第一个关键字50,然后想尽办法将它放到一个位置,使得它左边的值都比它小,右边的值都比它大,我们将这样的关键字成为枢轴(pivot)。

在经过Partition(L,1,9)的执行后,数组就变成{20,10,40,30,50,70,80,60,90},并返回5给pivot,数字5表明50放置在数组下标为5的位置,这时候你是否发现,50左边的值均比它小,右边的值都比它大。后面的递归调用"Qsort(L,1,5-1);"和"Qsort(L,5+1,9)"语句,其实就是在对{20,10,40,30}和{70,80,60,90}进行同样的Partition操作,直到顺序全部正确为止。


下面就来看看核心函数Partition的实现。

/* 交换顺序表L中子表的记录,使枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它 */

int Partition ( SqList *L,int low,int high)
{int pivotkey;pivotkey = L->r[low];   /* 用子表的 第一个记录作枢轴记录 */while(low < high)   /* 从表的两端交替向中间扫描 */{while(low < high && L->r[high] >= pivotkey)    high - - ;swap(L,low,high);    /* 将比枢轴记录小的记录交换到低端 */while(low < high && L->r[low] <= pivotkey )   low ++;swap(L,low,high);  /* 将比枢轴记录大的记录交换到高端 */}return low;   /*  返回枢轴所在位置 */
}

我们照着代码来分析:



可以看出Partition函数,其实就是将选取的pivotkey不断交换,将比它小的换到左边,比它大的换到右边,它也在交换中不断更改自己的位置,直到完全满足这个要求为止。

我在这里就不分析快排的时间和空间复杂度了,那些数字符号不想打,哈哈。快速排序的时间复杂度是O(nlogn),空间复杂度为O(logn)。

最后注明一下,快速排序是一种不稳定的排序方法,因为它的关键字比较和交换是跳跃进行的。如果有人不清楚什么是稳定和不稳定算法,百度一下就知道啦!我在这里就不说了,在接下来一篇博客,我将带领大家一起去优化我们当前说的快速排序。是的,兜了大半天,我们当前的快速排序算法还不是最好的,还有很多地方可以优化呢~哈哈

附上Java语言编写的快速排序算法,比我们用c语言实现的思路要更加清晰,大家自行分析吧!

public static void quickSort(int a[], int start, int end)
{       inti,j;i= start;j= end;if((a==null)||(a.length==0))return;while(i<j){while(i<j&&a[i]<=a[j]){    //以数组start下标的数据为key,右侧扫描j--;}if(i<j){                  //右侧扫描,找出第一个比key小的,交换位置int temp = a[i];a[i]= a[j];a[j]= temp;}while(i<j&&a[i]<a[j]){   //左侧扫描(此时a[j]中存储着key值)i++;}if(i<j){                //找出第一个比key大的,交换位置int temp = a[i];a[i]= a[j];a[j]= temp;}}if(i-start>1){//递归调用,把key前面的完成排序quickSort(a,start,i-1);}if(end-i>1){quickSort(a,i+1,end);   //递归调用,把key后面的完成排序}
}

注:参考书籍《大话数据结构》,文中的图片均出自该书。

更多推荐

浅谈快速排序

本文发布于:2024-03-13 02:12:57,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1732955.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:浅谈   快速

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!