对于快排而言,其核心在partition中,主要是对于pivot的选取上,所以我们可以按以下三种方案进行优化:

1.在数组长度大于某一个阈值范围时,我们进行递归快排,当数据长度小于阈值时,我们进行插入排序。

2.在partition中选取pivot时,选取首尾中的进行比较,选取中位数为pivot,以保证pivot能够尽可能的固定在中间,而让两端递归的子数组更加均衡。

3.进行三路partition优化。即将数组划分为左边小于pivot,中间等于pivot,右边大于pivot,这样两端递归时可以缩小递归数组的大小,大大提高效率。

第三种算法代码如下:

private void quickSort(int[] a, int left, int right) {if (right <= left)return;/* * 工作指针* p指向序列左边等于pivot元素的位置* q指向序列右边等于Pivot元素的位置* i指向从左向右扫面时的元素* j指向从右向左扫描时的元素*/int p, q, i, j;int pivot;// 锚点i = p = left;j = q = right - 1;/** 每次总是取序列最右边的元素为锚点*/pivot = a[right];while (true) {/** 工作指针i从右向左不断扫描,找小于或者等于锚点元素的元素*/while (i < right && a[i] <= pivot) {/** 找到与锚点元素相等的元素将其交换到p所指示的位置*/if (a[i] == pivot) {swap(a, i, p);p++;}i++;}/** 工作指针j从左向右不断扫描,找大于或者等于锚点元素的元素*/while (left <= j && a[j] >= pivot) {/** 找到与锚点元素相等的元素将其交换到q所指示的位置*/if (a[j] == pivot) {swap(a, j, q);q--;}j--;}/** 如果两个工作指针i j相遇则一趟遍历结束*/if (i >= j)break;/** 将左边大于pivot的元素与右边小于pivot元素进行交换*/swap(a, i, j);i++;j--;}/** 因为工作指针i指向的是当前需要处理元素的下一个元素* 故而需要退回到当前元素的实际位置,然后将等于pivot元素交换到序列中间*/i--;p--;while (p >= left) {swap(a, i, p);i--;p--;}/** 因为工作指针j指向的是当前需要处理元素的上一个元素* 故而需要退回到当前元素的实际位置,然后将等于pivot元素交换到序列中间*/j++;q++;while (q <= right) {swap(a, j, q);j++;q++;}/** 递归遍历左右子序列*/quickSort(a, left, i);quickSort(a, j, right);
}private void quick(int[] a) {if (a.length > 0) {quickSort(a, 0, a.length - 1);}
}private void swap(int[] arr, int a, int b) {int temp = arr[a];arr[a] = arr[b];arr[b] = temp;
}

其核心思想是:设置四个游标,左端a、b,右端c、d。b、c的作用跟之前两路划分时候的左右游标相同,就是从两端向中间遍历序列,并将遍历到的元素与pivot比较,如果等于pivot,则移到两端(b对应的元素移到左端,c对应的元素移到右端。移动的方式就是拿此元素和a或d对应的元素进行交换,所以a和d的作用就是记录等于pivot的元素移动过后的边界),反之,如果大于或小于pivot,还按照之前两路划分的方式进行移动。这样一来,中间部分就和两路划分相同,两头是等于pivot的部分,我们只需要将这两部分移动到中间即可。

快排的三种优化方式。相关推荐

  1. 三种快排及四种优化方式

    本文是转载文章,文章的来源:csdn博客 博主:silentsharer 文章: 三种快排及四种优化方式 博文地址:https://blog.csdn.net/hacker00011000/artic ...

  2. 数据结构之排序【归并排序和快排的顶级优化和快排的三种原理的实现及分析】 内含动态演示图

    文章目录 引言: 1.归并排序(MergeSort) 2.快速排序的优化(顶级优化) 3.快速排序的三种思路的代码实现及分析 4.归并排序和快排第3原理的测试 引言: 刚刚去回顾了一下递归实现的几个小 ...

  3. C语言快速排序算法及三种优化方式

    C语言快速排序算法及三种优化方式 C语言快速排序算法及三种优化方式 原理 快速排序复杂度分析 1 时间复杂度 2 空间复杂度 快速排序代码实现 1 普通快速排序 2 快速排序优化1-三数取中优化不必要 ...

  4. 快排 递归三种方式+非递归 --排序

    方法1–Hoare #include"Sort.h" void PrintArray(int* a, int n) {for (int i = 0; i < n; ++i){ ...

  5. 快排及7种优化 (海贼班 胡船长 第四次直播笔记 )

    这一次直播是闲话最少的,之前的直播有好久都是在推销课程 quick sort 是leetcode 912 我一直有个困惑,就是时间复杂度上,函数调用,判断什么的,都是O(1),但是具体是多少呢,底层是 ...

  6. 快速排序——三种划分方式

    思路: 1.分治思想:先划分成两个问题,然后对两个子问题递归排序,最后再合并. 2.核心算法:快排的核心在于划分问题(找到分界点). 代码: //快速排序 public static void qui ...

  7. 快速排序三种实现方式及其优化

    快速排序三种实现方式及其优化 1.关于快速排序 快速排序是分治法的一个应用. 根据分治法的思想,快速排序算法可描述为: 分解∶数组A[p-r]被划分为两个子数组A[p-q-1]和A[q+1,r],使得 ...

  8. 【黑帽大牛】浅谈SEO快排系统对网站排名优化真的有帮助吗?【精品】

    大家好,今天我们要跟大家探讨的问题是"[黑帽大牛]浅谈SEO快排系统对网站排名优化真的有帮助吗?".以下案例参考战神快排系统. 之前有太多的人私聊我:汉文黑帽大牛,我想问一下现在百 ...

  9. FPGA之道(41)HDL的三种描述方式

    文章目录 前言 三种描述方式 结构化描述方式 数据流描述方式 行为级描述方式 前言 常编写Verilog代码的就会知道,我们对于某一功能的描述,可以通过门电路来描述,也可以直接描述其功能等,这就牵扯到 ...

最新文章

  1. QIIME 2用户文档. 21图形界面q2studio(2019.7)
  2. Java反射机制简单使用
  3. asp.net中上传图片并生成小图片,自动添加水印的代码 .
  4. Keras TensorFlow教程:如何从零开发一个复杂深度学习模型
  5. matlab中find()函数用法
  6. HDU1251 统计难题 trie树 简单
  7. Leetcode--134. 加油站
  8. 文件管理服务器数据库,Oracle数据库服务器参数文件管理教程
  9. 2017二级c语言选择题,2017年9月计算机二级C语言考试选择题
  10. Android项目同步,如何通过gradle任务同步Android项目?
  11. 使用RouteDebugger对MVC路由进行调试
  12. 标准模板库(STL)之 priority_queue 列传
  13. Dijkstra算法详解:
  14. 2011最赚钱的行业和公司排行榜(verified 版本)
  15. ppt设置外观样式_ppt设置主题样式的方法步骤详解
  16. 如何通过iTunes安装ipa测试包
  17. Ps UI设计如何简单快捷切图
  18. 中国天气网 天气预报API 国家气象局 根据城市名称抓取城市ID,XML格式、JSON格式、图片代码
  19. android微单,用相机打电话 国产安卓系统微单了解一下
  20. 3 Linux 10个主流发行版本

热门文章

  1. android画笔,Android自定义View系列之画笔(一)
  2. 变位词算法C语言,程序实现英语变位词的搜索算法
  3. ASM入网小助手卸载
  4. spark输出rdd数据_Spark中RDD的详解
  5. MATLAB串联RLC响应
  6. 微信小程序—半圆(弧形)进度条
  7. 计算机组成原理DROM,最新版 计算机组成原理试题及答案a
  8. 最受程序员欢迎的 20 本书!
  9. 操作Excel导入的问题(转)
  10. 计算机图形学:实验二——OpenGL绘制基本图形