快速排序(Quick Sort)及优化
原理介绍
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
具体实现
左右指针法
实现说明
代码实现
public static void sort1(int[] arr, int start, int end) {
if (start >= end) {
return;
}
int key = end;
int left = start;
int right = end - 1;
int temp;
//当left和right相遇时结束
while (left < right) {
//移动left至第一个大于基准的元素
while (left < right && arr[left] <= arr[key]) {
left++;
}
//移动right至第一个小于基准的元素
while (left < right && arr[right] >= arr[key]) {
right--;
}
//交换left和right元素
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
//交换相遇位置和基准
if (arr[left] > arr[key]) {
temp = arr[left];
arr[left] = arr[key];
arr[key] = temp;
}
//递归
sort1(arr, start, left - 1);
sort1(arr, right + 1, end);
}
细节说明
下面的代码为什么还要判断left < right?
while (left < right && arr[left] <= arr[key])
key是序列的最后一个,right是key前一个位置,如果arr[right]=arr[key],满足arr[left]<=arr[key],然后left++,这时候left就会移动到key的位置
出了while循环并不是直接进行交换
if (arr[left] > arr[key]) {
temp = arr[left];
arr[left] = arr[key];
arr[key] = temp;
}
当left和right重合时,由于不满足left<right退出while循环不会继续右移left,若此时left元素依然小于基准元素则无需进行交换。
挖坑法
实现说明
代码实现
public static void sort2(int[] arr, int start, int end) {
if (start >= end) {
return;
}
int mark = arr[end];
int left = start;
int right = end;
int key = end;
//当left和right重合时结束
while (left < right) {
//left右移至第一个大于基准的位置
while (left < right && arr[left] <= mark) {
left++;
}
//将left元素填入坑中,令left位置为新坑
arr[key] = arr[left];
key = left;
//right左移至第一个小于基准的位置
while (left < right && arr[right] >= mark) {
right--;
}
//将right元素填入坑中,令right位置为新坑
arr[key] = arr[right];
key = right;
}
//将基准元素放入重合位置
arr[left] = mark;
sort2(arr, start, left - 1);
sort2(arr, right + 1, end);
}
由于坑位和right都为end,进行简化
public static void sort3(int[] arr, int start, int end) {
if (start >= end) {
return;
}
int mark = arr[end];
int left = start;
int right = end;
//当left和right重合时结束
while (left < right) {
//left右移至第一个大于基准的位置
while (left < right && arr[left] <= mark) {
left++;
}
//将left元素填入坑中,令left位置为新坑
arr[right] = arr[left];
//right左移至第一个小于基准的位置
while (left < right && arr[right] >= mark) {
right--;
}
//将right元素填入坑中,令right位置为新坑
arr[left] = arr[right];
}
//将基准元素放入重合位置
arr[left] = mark;
sort2(arr, start, left - 1);
sort2(arr, right + 1, end);
}
前后指针法
- 实现说明
代码实现
public static void sort4(int[] arr, int start, int end){
if (start >= end) {
return;
}
int key = end;
int cur = start;
int pre = cur - 1;
int temp;
//结束循环时cur在基准处
while (cur < key) {
//当cur元素小于基准元素时才会pre++
if (arr[cur] < arr[key] && ++pre != cur) {
temp = arr[cur];
arr[cur] = arr[pre];
arr[pre] = temp;
}
cur++;
}
temp = arr[cur];
arr[cur] = arr[++pre];
arr[pre] = temp;
sort4(arr, start, pre - 1);
sort4(arr, pre + 1, end);
}
优化方案
三数取中
选用待排数组最左边、最右边和最中间的三个元素的中间值作为基准
随机选取基准
在待排序列是部分有序时,固定选取枢轴使快排效率底下,要缓解这种情况,就引入了随机选取枢轴
根据分区大小调整算法
当分区的规模达到一定小时,停止快速排序算法,使用选择排序等算法
相同元素相聚
在一次分割结束后,可以把与Key相等的元素聚在一起,继续下次分割时,不用再对与key相等元素分割
在划分过程中,把与key相等元素放入数组的两端
划分结束后,把与key相等的元素移到基准周围
快速排序(Quick Sort)及优化的更多相关文章
- [算法] 快速排序 Quick Sort
快速排序(Quick Sort)使用分治法策略. 它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小.然后,再按此方法对这 ...
- 基础排序算法之快速排序(Quick Sort)
快速排序(Quick Sort)同样是使用了分治法的思想,相比于其他的排序方法,它所用到的空间更少,因为其可以实现原地排序.同时如果随机选取中心枢(pivot),它也是一个随机算法.最重要的是,快速排 ...
- 快速排序Quick sort
快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归 ...
- Java中的经典算法之快速排序(Quick Sort)
Java中的经典算法之快速排序(Quick Sort) 快速排序的思想 基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对 ...
- 排序算法 - 快速排序(Quick Sort)
算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想 ...
- quicksort 快速排序 quick sort
* Java基本版 package cn.mediamix; import java.util.LinkedList; public class QuickSort { public static v ...
- 基础算法之快速排序Quick Sort
原理 快速排序(Quicksort)是对冒泡排序的一种改进. 从数列中挑出一个元素,称为"基准"(pivot); 排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的 ...
- 快速排序算法回顾 --冒泡排序Bubble Sort和快速排序Quick Sort(Python实现)
冒泡排序的过程是首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字.以此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止 ...
- 快速排序——Quick Sort
基本思想:(分治) 先从数列中取出一个数作为key值: 将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边: 对左右两个小数列重复第二步,直至各区间只有1个数. 辅助理解:挖坑填数 初 ...
- 排序:快速排序Quick Sort
原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序 ...
随机推荐
- lattice diamond fpga 状态机的理解
比如序列检测101,需要三个状态 :so,s1,s2. 思路:(1)s0状态有两种情况0或1,若为0时在自身打圈,是1时进入s1状态. (2)s1状态有两种0或1,若为1自身打圈,因为1可以作为下次检 ...
- linux 命令——49 at (转)
在windows系统中,windows提供了计划任务这一功能,在控制面板 -> 性能与维护 -> 任务计划, 它的功能就是安排自动运行的任务. 通过'添加任务计划'的一步步引导,则可建立一 ...
- linux 命令——13 less(转)
less 工 具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性. 在 more 的时候,我们并没有办法向前 ...
- js高级笔录
1.类型转换①转换成字符串toString() ⅰBoolean 值.数字和字符串的原始值的有趣之处在于它们是伪对象,这意味着它们实际上具有属性和方法. var sColor = "red& ...
- Objective-C try/catch异常处理机制原理。
try-catch-finaly finally在任何情况下都会执行(不管有没有异常),属于整个体系的附属. 基本思想是跳到捕获锚点,重新执行. http://www.cnblogs.com/mark ...
- S运算符&&和|| 及其优先级
a && b : 将a, b转换为Boolean类型, 再执行逻辑与, true返回b, false返回aa || b : 将a, b转换为Boolean类型, 再执行逻辑或, tru ...
- 01_15_Struts2_带参数的结果集
01_15_Struts2_带参数的结果集 1. 背景说明 服务器端页面跳转的时候,通过struts提供的标签的valuestack可以直接取.服务器端的转发,valuestack的对象属性可以共享. ...
- js中的||、&&与!用法
&&和||在JQuery源代码内尤为使用广泛,由网上找了些例子作为参考,对其用法研究了一下: 1. && function a(){ alert("a&quo ...
- 二、Shell 变量
Shell 变量 定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_name="runoob.com" 注意,变量名和等号之间不能有空格,这可能和你熟悉的 ...
- Install Jenkins 2.1.36 and openjdk 1.7.0 on centos 7
#!/bin/bash## Copyright (c) 2014-2015 Michael Dichirico (https://github.com/mdichirico)# This softwa ...