交换排序—快速排序(Quick Sort)
来源:互联网 发布:公司数据管理制度 编辑:程序博客网 时间:2024/06/05 04:43
交换排序—快速排序(Quick Sort)
- 交换排序快速排序Quick Sort
- 基本思想
- 排序流程
- 1 基本流程
- 2 排序实例
- 算法实现
- 1 基本快速排序
- 2 算法改进
- 算法分析
- 交换排序快速排序Quick Sort
快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1962年提出。
1. 基本思想
快速排序采用的思想是分治思想。
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
2. 排序流程
2.1 基本流程
(1)选择一个基准元素,通常选择第一个元素或者最后一个元素;
(2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大;
(3)此时基准元素在其排好序后的正确位置;
(4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
2.2 排序实例
(a)一趟排序:
(b)排序全程:
3. 算法实现
3.1 基本快速排序
给定序列{A[0], A[1], … , A[N-1]}。
一趟快速排序的算法是:
(1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
(2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
(3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key的值A[j],将A[j]和A[i]互换;
(4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
(5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
代码
/* 快速排序--升序 */void quick_sort(int *a, int left, int right){ if(left >= right) /* 如果左边索引大于或者等于右边的索引,则已完成 */ { return ; } int i = left; int j = right; int key = a[left]; /* 基准元素 */ while(i < j) /* 组内搜索 */ { while(i < j && key <= a[j]) /* j向前搜索小于key的数,结束条件:1.找到一个小于等于key的数(降序为大于key)2.无符合条件1的,直到j等于i */ { j--; /* 向前搜索 */ } a[i] = a[j]; /* 将找到的数换到位置key上,如果没找到i=j就是本身 */ while(i < j && key >= a[i]) /* i向后搜索大于key的数,结束条件:1.找到一个大于等于key的数(降序为小于key)2.无符合条件1的,直到i等于j */ { i++; /* 向后搜索 */ } a[j] = a[i]; /* 将找到的数换到位置key上,如果没找到i=j就是本身 */ } a[i] = key;/* 组内搜索完毕,key放在正确的位置上,此时key前面都小于等于key,后面都大于等于key */ step++; print(a,left,right); /* 递归前打印 */ quick_sort(a, left, i - 1);/* 对于前面的组重复组内搜索 */ quick_sort(a, i + 1, right);/* 对于后面的组重复组内搜索 */ /* 递归每一个小组,直至所有组的i=j */}
结果
Before...No.0 4 7 1 2 9 5 3 8 6 [0, 0]Sorting...No.1 3 2 1 4 9 5 7 8 6 [0, 8]No.2 1 2 3 4 9 5 7 8 6 [0, 2]No.3 1 2 3 4 9 5 7 8 6 [0, 1]No.4 1 2 3 4 6 5 7 8 9 [4, 8]No.5 1 2 3 4 5 6 7 8 9 [4, 7]No.6 1 2 3 4 5 6 7 8 9 [6, 7]Sorted.
3.2 算法改进
“三者取中”选取基准数
选取第一个A[0]、中间A[N/2]、最后一个A[N-1]中的中间数作为基准数,以防止基准数太大或太小。在划分开始前将该基准记录和该区的第 1 个数进行交换,此后的划分过程与基本算法完全相同。
随机选择基准数
选取 low 和 high 之间的随机数 k(low<=k<=high),用 A[k] 作为基准;选取基准最好的方法是用一个随机函数产生一个位于 low 和 high 之间的随机数 k(low<=k<=high) ,用 A[k] 作为基准 , 这相当于强迫 R[low, … high] 中的记录是随机分布的。用此方法所得到的快速排序一般称为随机的快速排序
排序方法结合
当快速排序递归至区间内数据较少(设置阈值k,即小于k)时,直接用其他方法排序以减小递归深度。
4. 算法分析
时间复杂度
(1)快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。
(2)最坏情况下,每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为
O(n2) 。(3)最好情况下,每次划分所取的基准都是当前无序区的”中值”记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:
O(nlogn) (4)平均性能,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名,快速排序是实践中已知最快的排序算法。它的平均时间复杂度为
O(nlogn) 。空间复杂度
快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为
O(logn) , 故递归后所需栈空间为O(logn) 。最坏情况下,递归树的高度为O(n) ,所需的栈空间为O(n) 。稳定性
快速排序是一个不稳定的排序方法。
- 交换排序—快速排序(Quick Sort)
- 交换排序—快速排序(Quick Sort)
- 交换排序—快速排序(Quick Sort)
- 交换排序—快速排序(Quick Sort)
- 排序---交换排序---快速排序Quick Sort
- 【排序算法】 快速排序 quick sort(交换类排序)
- 交换排序算法:快速排序-Quick Sort
- 快速排序(quick sort)
- 快速排序(quick sort)
- 快速排序(quick sort)
- 快速排序(Quick Sort)
- 快速排序(Quick sort)
- 快速排序(Quick Sort)
- 快速排序(Quick Sort)
- 快速排序(Quick Sort)
- 快速排序(Quick Sort)
- 快速排序(Quick Sort)
- Quick Sort(快速排序)
- vSphere Client 不能编译版本为10 或更高版本 的虚拟机
- WebGL 3D 数百个 HTML5 例子学习 HT 图形组件
- 百度富文本框ueditor使用教程
- [RK3288][Android6.0] 调试笔记 --- 普通串口的添加
- Qt获取打开,保存文件路径
- 交换排序—快速排序(Quick Sort)
- Java中无参带返回值的使用
- SQL事务
- PHP 面向对象设计原则--单一职责原则
- 关于app更新后部分用户点击icon图标会闪退的问题
- 双调欧几里得旅行商问题 hdu 2224 |hdu 4824 [动态规划]
- Android百分比布局
- 零基础学WEB前端-CSS
- C++学习笔记 lesson9 C++ string类