经典排序算法学习笔记二——快速排序
快速排序
数据结构 | 不定 |
---|---|
最差时间复杂度 | O(n^2) |
最优时间复杂度 | O (n*log n) |
平均时间复杂度 | O (n*log n) |
最差空间复杂度 | 根据实现的方式不同而不同 |
https://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F
1、算法思想
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
2、伪代码
function quicksort(q)//from 维基百科var list less, pivotList, greaterif length(q) ≤ 1 {return q} else {select a pivot value pivot from qfor each x in q except the pivot elementif x < pivot then add x to lessif x ≥ pivot then add x to greateradd pivot to pivotListreturn concatenate(quicksort(less), pivotList, quicksort(greater))}
QUICK_SORT(A,p,r)//from 算法导论if(p<r)thenq<——PARTITION(A,p,r)QUICK_SORT(A,p,q-1)QUICK_SORT(A,q+1,r)//核心函数,对数组A[p,r]进行就地重排,将小于A[r]的数移到数组前半部分,将大于A[r]的数移到数组后半部分。 // PARTITION(A,p,r)pivot<——A[r]i<——p-1forj<——ptor-1doifA[j]<pivoti<——i+1exchangeA[i]<——>A[j]exchangeA[i+1]<——>A[r] return i+1
3、C实现
迭代法
typedef struct _Range {int start, end; } Range; Range new_Range(int s, int e) {Range r;r.start = s;r.end = e;return r; } void swap(int *x, int *y) {int t = *x;*x = *y;*y = t; } void quick_sort(int arr[], const int len) {if (len <= 0)return; //避免len等於負值時宣告堆疊陣列當機//r[]模擬堆疊,p為數量,r[p++]為push,r[--p]為pop且取得元素 Range r[len];int p = 0;r[p++] = new_Range(0, len - 1);while (p) {Range range = r[--p];if (range.start >= range.end)continue;int mid = arr[range.end];int left = range.start, right = range.end - 1;while (left < right) {while (arr[left] < mid && left < right)left++;while (arr[right] >= mid && left < right)right--;swap(&arr[left], &arr[right]);}if (arr[left] >= arr[range.end])swap(&arr[left], &arr[range.end]);elseleft++;r[p++] = new_Range(range.start, left - 1);r[p++] = new_Range(left + 1, range.end);} }
递归法
#include <stdio.h> #include <stdlib.h> void swap(int *x, int *y) {int t = *x;*x = *y;*y = t; } void quick_sort_recursive(int arr[], int start, int end) {if (start >= end)return;//這是為了防止宣告堆疊陣列時當機int mid = arr[end];int left = start, right = end - 1;while (left < right) {while (arr[left] < mid && left < right)left++;while (arr[right] >= mid && left < right)right--;swap(&arr[left], &arr[right]);}if (arr[left] >= arr[end])swap(&arr[left], &arr[end]);elseleft++;quick_sort_recursive(arr, start, left - 1);quick_sort_recursive(arr, left + 1, end); } void quick_sort(int arr[], int len) {quick_sort_recursive(arr, 0, len - 1); } int main() {int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };int len = (int) sizeof(arr) / sizeof(*arr);int i;printf("before quick_sort:\n");for (i = 0; i < len; i++)printf("%d ", arr[i]);quick_sort(arr, len);printf("\nquick_sorted:\n");for (i = 0; i < len; i++)printf("%d ", arr[i]);system("pause");return 0; }
4、改进
——摘自维基百科
快速排序是二叉查找树(二叉查找树)的一个空间最优化版本。
对于排序算法的稳定性指标,原地分区版本的快速排序算法是不稳定的。其他变种是可以通过牺牲性能和空间来维护稳定性的。
快速排序的最直接竞争者是堆排序(Heapsort)。
快速排序也与归并排序(Mergesort)竞争,这是另外一种递归排序算法,但有坏情况O(n log n)运行时间的优势。
归并排序是一个稳定排序,且可以轻易地被采用在链表(linked list)和存储在慢速访问媒体上像是磁盘存储或网络连接存储的非常巨大数列。尽管快速排序可以被重新改写使用在炼串列上,但是它通常会因为无法随机存取而导致差的基准选择。
归并排序的主要缺点,是在最佳情况下需要Ω(n)额外的空间。
转载于:https://www.cnblogs.com/crystalmoore/p/5930298.html
经典排序算法学习笔记二——快速排序相关推荐
- 经典排序算法学习笔记七——堆排序
堆排序 数据结构 数组 最差时间复杂度 O(n*log n) 最优时间复杂度 O(n*log n) 平均时间复杂度 O(n*log n) 最差空间复杂度 О(n) total, O(1) auxili ...
- 常见经典排序算法学习总结(插入、shell、冒泡、选择、归并、快排等)
博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了 ...
- 经典排序算法(2)——快速排序算法详解
快速排序(Quick Sort)也是一种典型的交换排序算法,通过交换数据元素的位置进行排序. 一.算法基本思想 (1)基本思想 快速排序的基本思想就是:通过一趟排序将要排序的数据分割成独立的两部分,其 ...
- 【基础】排序算法学习笔记
NOIP范畴常见的排序一般是这几种 1.冒泡排序,选择排序,插入排序 2.快速排序,归并排序,堆排序 3.计数排序,基数排序,桶排序 前两类是基于比较的,第三类是基于统计的. 第一类都是O(N^2)的 ...
- 十大经典排序算法(下)
请查看相关文章:十大经典排序算法(上) 快速排序(Quick Sort) 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分 ...
- 十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序
养成习惯,先赞后看!!! 你的点赞与关注真的对我非常有帮助.如果可以的话,动动手指,一键三连吧!!! 十大经典排序算法-堆排序,计数排序,桶排序,基数排序 前言 这是十大经典排序算法详解的最后一篇了. ...
- 冒泡和快速排序的时间复杂度_排序算法学习分享(二)交换排序---冒泡排序与快速排序...
排序,也称为排序算法,可以说是我们学习算法的过程中遇到的第一个门槛,也是实际应用中使用得较为频繁的算法,我将自己对所学的排序算法进行一个归纳总结与分享,如有错误,欢迎指正! 排序算法学习分享(一)选择 ...
- 算法学习(二)快速排序(上)
快速排序采用的思想是分而治之. 1)将一整个大的无序序数组,根据数组中的某一个值,将数组分成两部分,一部分比这个值小,一部分比这个值大. 2)然后再对这两部分各自进行同样的操作,而当每一部分都有序之后 ...
- 数据结构与算法(十二):八大经典排序算法再回顾
文章出自汪磊的博客,未经允许不得转载 一.排序的理解 提到排序大部分同学肯定第一时间想到int数组的排序,简单啊,所谓排序不就是将int数组按照从大到小或者从小到大排序吗,如果我有个数组存放的不是in ...
最新文章
- cudnn7.6.5下载 solitairetheme8_.NET Framework 3.5 开启方法及微软官方原版下载
- OkHttp3 + retrofit2 封装
- VMware内存回收与分配机质
- Windows终端利器Cmder
- linux打包tar包命令,Linux压缩打包方法连载之一:tar命令
- ios7以后隐藏状态栏
- [SinGuLaRiTy] 二分图匈牙利算法
- (day9)357. 计算各个位数不同的数字个数
- spring 从源码学设计1-doDispatch()
- 名字正则只能是中文英文_【R语言新书】1.5 正则表达式
- oc引导win方法_适配自己的OC引导一键生成Opencore Generation X使用指南
- SOA架构中企业数据总线(ESB)和微服务架构中注册服务管理(dubbo)的区别
- Debug调试报错解决方案
- h5页面调用百度地图获取当前位置并在地图上标注出来
- Ubuntu16.04:GTX1650的显卡驱动安装
- bismark 识别甲基化位点-比对篇
- 自定义view----六边形战斗力图表
- MyBatis之Base64加密数据源
- 转载---about Amazon EC2
- apk下载链接(实时更新)
热门文章
- URAL 1671 Anansi's Cobweb (并查集)
- 求n边形周长的k等分点坐标(今日头条)
- win10注册mysql服务_win10下搭建MySQL服务
- Android Jetpack中CameraX保存Bitmap
- 学Python真的好找工作吗?工作多年的程序员为你解答
- 【创建一个网页,实现猜数字游戏】
- Graph Attention Network (GAT) 的Tensorflow版代码解析
- ## 论文学习—用一个可接受的的剪枝策略来加速动态时间规整聚类的算法
- Security and Communication Networks 论文投稿
- Windows 11 预览版来了?