希尔排序相当于直接插入排序的升级,它们同属于插入排序类,堆排序相当于简单选择排序的升级,同属于选择排序类,而接下来要说明的快速排序则是冒泡排序的一种升级,都属于交换排序类。

一、快速排序

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

二、快速排序算法实现

package Sort;/*** Created by LKL on 2017/3/4.*/
public class TestQuickSort {public static void main(String[] args){int[] adj = new int[]{5,1,9,8,3,7,4,6,2};print(adj);QuickSort(adj);}public static void QuickSort(int[] adj){QSort(adj,0,adj.length-1);}public static void QSort(int[] adj,int low,int high){int pivot;if(low<high){//将序列表一分为二,算出枢轴值pivot = Partition(adj,low,high);//对低子表递归排序QSort(adj,low,pivot-1);//对高子表递归排序QSort(adj,pivot+1,high);//打印输出每次的内容print(adj);}}/** 选出其中的一个关键字,放在一个合适的位置,* 使得左边的值都比它小,右边的值比它大,将它成为枢轴(pivot)** */public static int Partition(int[] adj,int low,int high){int pivotkey;pivotkey=adj[low];//从表的两端交替向中间扫描while(low<high){while(low<high&&adj[high]>=pivotkey){high--;}swap(adj,low,high);//将比枢轴记录小的交换到低端while(low<high&&adj[low]<=pivotkey){low++;}swap(adj,low,high);//将比枢轴记录大的交换到高端}return low;}public static void swap(int[] adj,int low,int high){int temp;temp=adj[low];adj[low]=adj[high];adj[high]=temp;}public static void print(int[] data) {for (int i = 0; i < data.length; i++) {System.out.print(data[i] + "\t");}System.out.println();}
}

运行结果如下:

5   1   9   8   3   7   4   6   2
1   2   3   4   5   7   8   6   9
1   2   3   4   5   7   8   6   9
1   2   3   4   5   6   7   8   9
1   2   3   4   5   6   7   8   9
1   2   3   4   5   6   7   8   9

三、快速排序优化

由于上述代码,我们是有一个假设性的操作,即假设pivot刚好处于low与high的中间,而事实并不会这么凑巧,当出现{9,1,3,5,2,4,7,6,8},此时pivot为9,转化后,并没有发生什么实质性的优化,因此有人想到了“三数取中法”,即取三个关键字先进行排序,将中间数作为枢轴,一般是取左端、右端和中间三个数。此时,pivot至少不会是最大或者最小了。
主要是修改了Patition方法,首先判定pivot不是最大,也不是最小。

 /** 选出其中的一个关键字,放在一个合适的位置,* 使得左边的值都比它小,右边的值比它大,将它成为枢轴(pivot)** */public static int Partition(int[] adj,int low,int high){int pivotkey;int m=low +(high-low)/2;if(adj[low]>adj[high]){swap(adj,low,high);}if(adj[m]>adj[high]){swap(adj,high,m);}if(adj[m]>adj[low]){swap(adj,m,low);}pivotkey=adj[low];//从表的两端交替向中间扫描while(low<high){while(low<high&&adj[high]>=pivotkey){high--;}swap(adj,low,high);//将比枢轴记录小的交换到低端while(low<high&&adj[low]<=pivotkey){low++;}swap(adj,low,high);//将比枢轴记录大的交换到高端}return low;}

四、快速排序复杂度分析

(1)快速排序最优的时间复杂度

快速排序最优的情况就是每一次取到的元素都刚好平分整个数组(很显然上面的不是);
此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间;
下面来推算下,在最优的情况下快速排序时间复杂度的计算(用迭代法):

       T[n] =  2T[n/2] + n       ------第一次递归

令:n = n/2 = 2 { 2 T[n/4] + (n/2) } + n —-第二次递归

            =  2^2 T[ n/ (2^2) ] + 2n

令:n = n/(2^2) = 2^2 { 2 T[n/ (2^3) ] + n/(2^2)} +2n ——-第三次递归

            =  2^3 T[  n/ (2^3) ]  + 3n......................................................................................                        令:n = n/(  2^(m-1) )    =  2^m T[1]  + mn                                                  ----------------第m次递归(m次后结束)当最后平分的不能再平分时,也就是说把公式一直往下跌倒,到最后得到T[1]时,说明这个公式已经迭代完了(T[1]是常量了)。

得到:
T[n/ (2^m) ] = T[1] ===>> n = 2^m ====>> m = logn;
T[n] = 2^m T[1] + mn ;其中m = logn;

           T[n] = 2^(logn) T[1] + nlogn  =  n T[1] + nlogn  =  n + nlogn  ;其中n为元素个数

又因为当n >= 2时:nlogn >= n (也就是logn > 1),所以取后面的 nlogn;

           综上所述:快速排序最优的情况下时间复杂度为:O( nlogn )。
(2)最差情况下时间复杂度
最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序),其时间复杂度为O(n^2)。
(3)平均时间复杂度为O(nlogn)
(4)空间复杂度:
最优的情况下空间复杂度为:O(logn);每一次都平分数组的情况;
最差的情况下空间复杂度为:O( n );退化为冒泡排序的情况。

文章只是作为自己的学习笔记,借鉴了网上的许多案例,如果觉得阔以的话,希望多交流,在此谢过…

排序篇(7)--快速排序相关推荐

  1. C语言排序篇:快速排序

    采用递归和交换思想.对于n个数排序,每次选出第0个和第n-1个下标设置为分别为LOW和HIGH.然后定义其中一个为key.基本流程为: a. 将High向左扫描,如果KEY小于Data[HIGH],继 ...

  2. 常用排序:冒泡排序与快速排序详解,看完这篇就够了!风马博客

    常用排序:冒泡排序与快速排序详解. 在排序算法中,冒泡排序和快速排序可以算是排序算法入门必会的两种排序了,今天和大家来分析一下如何快速理解并掌握这两种排序.首先冒泡排序是初学者最常用的排序,所以我们先 ...

  3. 十大排序算法之快速排序(两种方法)

    十大排序算法之快速排序 本文采用Java书写选择排序,其他语言类似可以借鉴着写 思想:在待排序序列中选择一个分割元素,将待排序序列中所有比分割元素关键字小的元素移动到分割元素左侧位置:将待排序序列中所 ...

  4. Java入门算法(排序篇)丨蓄力计划

    本专栏已参加蓄力计划,感谢读者支持 往期文章 一. Java入门算法(贪心篇)丨蓄力计划 二. Java入门算法(暴力篇)丨蓄力计划 三. Java入门算法(排序篇)丨蓄力计划 四. Java入门算法 ...

  5. 排序算法之----快速排序(快速上手快速排序)

    排序算法之----快速排序(快速上手快速排序) 何为快速排序算法? 快速排序的基本思想又是什么? 其实很简单: 快速排序的基本思想是 1.先从数列中取出一个数作为基准数(这里我们的算法里面取数组最右边 ...

  6. C#算法设计排序篇之04-选择排序(附带动画演示程序)

    选择排序(Selection Sort) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/681 访问. 选择排序是一种简 ...

  7. 推荐系统技术演进趋势:排序篇

    作者 | 张俊林 编辑 | 炼丹笔记 <推荐系统技术演进趋势>从召回篇.排序篇.重排篇依次更新,本文为排序篇.错过<推荐系统技术演进趋势:召回篇>的小伙伴可以点击链接跳转阅读. ...

  8. php1到5000排序,常用的排序算法(一)--快速排序(PHP实现)

    常用的排序算法系列 快速排序 假设当前需要从小到大进行排序,快速排序的核心思路是,从当前数组中,找到一个元素作为基准比较值(key),分别从两个方向进行比较.从后往前找,比key小元素放在数组前面.然 ...

  9. 数据结构实验之排序八:快速排序

    数据结构实验之排序八:快速排序 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 给定N ...

最新文章

  1. 单目深度估计与伪雷达点云、可视化
  2. 算法笔记_204:第四届蓝桥杯软件类决赛真题(Java语言C组)
  3. DbHelper数据操作类,DbProviderFactories
  4. Oracle Drop表并未直接删除 drop table xx purge
  5. [20180826]四校联考
  6. STM32_ADC初始化参数说明以及常用的固件库
  7. 自适应滤波——线性预测(LPC)
  8. 函数和存储过程的区别
  9. mysql导入.sql文件中文乱码_mysql通过sql文件导入数据时出现乱码的解决办法
  10. PCL中3D点云特征描述与提取(一)
  11. 无线通信原理之OFDM技术
  12. python 安全编码代码审计
  13. RSA2048 private key der格式结构
  14. 常见的 NoSQL 数据库有哪些?一篇详尽(图表展示)
  15. 听说go语言越来越火了?那么请收下这一份go语言书单吧!
  16. Oracle--ORA-01775: 同义词的循环链
  17. VS2019 Community许可证过期
  18. 彩色空间(Color Space)
  19. 高效学英语 - 统计英文书词频
  20. 自行实现ONVIF协议网络摄像机(IPC)开发(0):专栏开篇

热门文章

  1. gradle project详解
  2. JSONP 是什么?
  3. 赵信的往事 南邮NOJ2069
  4. 播客丨化繁为简,低代码漫谈
  5. 虚拟服务器的1核对应,云服务器的1核是指什么
  6. Python3 | 通过百度地图API获取商家详细信息(包括店名,地址,经纬度,电话)
  7. 在邮件中自动播放flash
  8. 任务创建 app.c代码讲解
  9. Assert.isTrue 意思是反的
  10. 【新课上架】Substance Painter 2018 基础实例教程