QuickSort 快速排序算法
2014-04-22 21:50
211 查看
引子:快速排序算法,被列为 20 世纪 十大算法之一。
希尔排序相当于直接插入排序的升级,只是增加了increment的设置,利用了基本有序的思想,同属于插入排序类。堆排序相当于简单选择排序的升级,他们同属于选择排序类,只是通过构建堆(完全二叉树)的方式,让选择最大项更加快速。而快速排序其实就是我们前面认为最慢的冒泡排序的升级,他们同属于交换排序类。即它也是通过不断比较和移动交换来实现排序的,不过它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减小了比较次数和移动交换次数。
基本思想:(Quick Sort )通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
复杂度
时间复杂度 o(n log n)
空间复杂度 o(log n)
优化:
1. 优化选取枢纽(三数取中、九数取中),上述代码中,枢纽选择都是第一个元素,如果是最大或者最小元素,则会成为单只树。
2. 优化不必要的交换(将 pivotkey 被分到 L.r[0]中,然后是swap时,只做替换的工作,最终当 low 与 high 会和,即找到了枢轴的位置时,再将L.r[0] 的数值 赋值回 L.r[low]),因此减少了多次交换数据的操作。
3. 优化小数组时的排序方案(小数组时候,选用直接插入排序,快排对小数组排序没有优势,可能还要慢于最简单的插入排序)
4. 优化递归操作(对QSort实施尾递归优化,减小递归深度,提高效率)
希尔排序相当于直接插入排序的升级,只是增加了increment的设置,利用了基本有序的思想,同属于插入排序类。堆排序相当于简单选择排序的升级,他们同属于选择排序类,只是通过构建堆(完全二叉树)的方式,让选择最大项更加快速。而快速排序其实就是我们前面认为最慢的冒泡排序的升级,他们同属于交换排序类。即它也是通过不断比较和移动交换来实现排序的,不过它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减小了比较次数和移动交换次数。
基本思想:(Quick Sort )通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
代码: /* 对顺序表 L 作快速排序 */ void QuickSort( SqList *L ) { QSort( L, 1, L->length ); } /* 对顺序表 L 中的子序列 L->r[low...high]作快速排序 */ void QSort( SqList *L, int low, int high ) { int pivot; if( low < high ) //递归条件出口 { pivot = Partition(L, low, high); /* 将L->r[low...high]一分为二 */ /* 算出枢纽值 pivot */ QSort(L, low, pivot-1); QSort(L, pivot+1, high); } } /* 交换顺序表 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往左找,找到一个比 pivotkey小的元素 */ high--; swap(L, low, high ); /* 右小 左大 互换 */ while(low < high && L->r[low] <= pivotkey ) /* 从low往右找,找到一个比pivotkey大的元素 */ low++; swap(L, low, high); /* 左大 右小 互换 */ } /* 最后结束循环,low 与 high 相等,返回low,返回位置 */ return low;
复杂度
时间复杂度 o(n log n)
空间复杂度 o(log n)
优化:
1. 优化选取枢纽(三数取中、九数取中),上述代码中,枢纽选择都是第一个元素,如果是最大或者最小元素,则会成为单只树。
2. 优化不必要的交换(将 pivotkey 被分到 L.r[0]中,然后是swap时,只做替换的工作,最终当 low 与 high 会和,即找到了枢轴的位置时,再将L.r[0] 的数值 赋值回 L.r[low]),因此减少了多次交换数据的操作。
3. 优化小数组时的排序方案(小数组时候,选用直接插入排序,快排对小数组排序没有优势,可能还要慢于最简单的插入排序)
4. 优化递归操作(对QSort实施尾递归优化,减小递归深度,提高效率)
相关文章推荐
- [codility]GenomicRangeQuery
- UEditor
- UT报错误:A granted authority textual representation is required
- Java中尽量使用StringBuilder和StringBuffer进行字符串连接
- leetCode解题报告5道题(五)
- [ACM] poj 1141 Brackets Sequence (动态规划)
- [ACM] poj 1141 Brackets Sequence (动态规划)
- [ACM] poj 1141 Brackets Sequence (动态规划)
- ios学习记录 day37 UI13中级数据持久化(数据库)
- structs中通过LabelValueBean构建下拉列表
- 【LabVIEW之UI】LabVIEW双指针量表与表盘梯度颜色
- Parameter Maps collection does not contain value for XXX.map
- POJ 2524 Ubiquitous Religions
- CGImageRef 与 UIImage
- SQLServer DMV Query
- UIImage 图片处理
- solr multivalued
- Query语法高亮插件,代码上色,页面代码着色
- 细说 QUEST CENTRAL FOR DB2 八宗罪
- WeifenLuo.WinFormsUI.Docking小应用