Python数据结构与算法——第五十三课 快速排序

  快速排序是冒泡排序的改进型,是基于分治的思想的排序类型。首先从待排序数组中取出第1个数作为基数,然后把数组中比此数小的全部移动到此数左侧,再把比此数大的移动到此数右侧,第1轮排序完毕;然后把整个数组在此基数位置上二分,左右子数组再按上述做法再次移动一轮算第2轮排序完成,以此类推,直至所有子数组皆成有序状态。

  快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。

  最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅比刻分前的无序区中记录个数减少一个,时间复杂度为O(n²);在最好情况下,每次划分所取的基准都是当前无序区的中值记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数为O(nlog2n)

  尽管快速排序的最坏时间复杂度为O(n²),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。快速排序的时间复杂度(平均)是O(nlog2n)、空间复杂度是O(nlog2n),为不稳定排序算法(采用分组)。

  比如,待排序数组arr=[8,4,5,12,7,1,3,6,2],用快速排序方法对这个数组做排序的图解分析如下图所示。

 

  程序代码:

 

 

  运行结果:

 

  从算法中可知道,每次运行都会固定一个基准元素的位置,因此只要有一个列表收集分组(基准元素作为中间分组)就可以用循环实现算法。

  程序代码:

 

 

 

  运行结果:

 

 

  练习题1:下面是一批学生的姓名、学号和数学成绩,请用两种快速排序法排序,使高分在前,低分在后;同分学号小的在前,学号大的在后。

姓名   学号   分数

李大伟  23   90,

黄晨希  15   88,

张丹丹  11   90,

王丽丽  21   95,

刘华旭  12   88,

李小明   9   94,

霍顺高   5   97,

张飞鹏  10   88,

李华峰   3   99,

史大维   8   90,

黄芬诗   2   97。

 

  学思营编程课堂基于蓝桥STEM86平台https://www.stem86.com,开展学编程三部曲:

Scratch(三年级以前)>>>Python(四年级以后)>>>C++(七年级以后)教育实验活动,任何人可以免费参加,打开https://xuesiying.stem86.com网页注册进入课堂,也可关注本公众号留言。

更多课程请打开学思营同步网站:

http://www.5xstar.com/doc.html

 

参考资料:

1、《Python算法图解》何韬编著 清华大学出版社