快速分类–三向和双枢轴

毫无疑问,Quicksort被认为是本世纪最重要的算法之一,并且它是许多语言(包括Java中的Arrays.sort )的事实上的系统排序。

那么,quicksort有何新功能?

嗯,除了我现在(在Java 7发行了2年之久)才想到, Arrays.sort的Quicksort实现已被替换为Dual-Pivot QuickSort的变体代替了。 出于这个原因,这个线程真棒,而且乔恩·本特利和约书亚·布洛赫真的很谦虚。

接下来我要做什么?

就像其他所有人一样,我想实现它并针对约1000万个整数(随机和重复)进行一些基准测试。

奇怪的是,我发现以下结果:

随机数据:

  • 快速排序基本:1222毫秒
  • 快速排序3种方式:1295毫秒(严重!)
  • 快速分类双枢轴:1066毫秒

重复数据:

  • 快速排序基础:378毫秒
  • 快速排序3种方式:15毫秒
  • 快速分类双枢轴:6毫秒

愚蠢的问题1:

恐怕在三向分区的实现中缺少一些东西。 在针对随机输入(1000万个)数字的多次运行中,我可以看到单个枢轴始终表现更好(尽管对于1000万个数字,相差不到100毫秒)。

我知道直到现在,将3-way Quicksort设置为默认Quicksort的全部目的是它不会在重复键上提供0(n 2)性能-当我对重复输入运行它时,这一点非常明显。 但是,为了处理重复的数据,三路方式会付出一点代价吗? 还是我的实现不好?

愚蠢的问题2

我的Dual Pivot实现(下面的链接)不能很好地处理重复项。 它需要永远的甜蜜(0(n 2))才能执行。 有避免这种情况的好方法吗? 谈到Arrays.sort实现,我发现在完成实际排序之前,就消除了升序和重复项。 因此,作为一个肮脏的解决方法,如果枢轴相等,则我快进lowerIndex,直到它与pivot2不同。 这是一个公平的实施吗?

else if (pivot1==pivot2){while (pivot1==pivot2 && lowIndex<highIndex){lowIndex++;pivot1=input[lowIndex];}}

而已。 那就是我所做的一切?

我总是发现算法的跟踪很有趣,但是由于Dual Pivot quicksort中的变量数量众多,我的眼睛在调试时发现它不知所措。 因此,我还继续创建了启用跟踪的实现(针对所有3种实现),以便可以看到变量指针当前所在的位置。

这些启用了跟踪的类仅覆盖指针在数组值下方的位置。 我希望您发现这些课程有用。

例如。 用于Dual Pivot迭代

快速排序追踪

整个项目(以及DSA的一些la脚实现)可在github上找到 。 仅在这里可以找到 quicksort类。

这是我对SinglePivot(Hoare),3路(Sedgewick)和新的Dual-Pivot(Yaroslavskiy)的实现

单枢轴

Optimized-SinglePivot.png

package basics.sorting.quick;import static basics.sorting.utils.SortUtils.exchange;
import static basics.sorting.utils.SortUtils.less;
import basics.shuffle.KnuthShuffle;public class QuickSortBasic {public void sort (int[] input){//KnuthShuffle.shuffle(input);sort (input, 0, input.length-1);}private void sort(int[] input, int lowIndex, int highIndex) {if (highIndex<=lowIndex){return;}int partIndex=partition (input, lowIndex, highIndex);sort (input, lowIndex, partIndex-1);sort (input, partIndex+1, highIndex);}private int partition(int[] input, int lowIndex, int highIndex) {int i=lowIndex;int pivotIndex=lowIndex;int j=highIndex+1;while (true){while (less(input[++i], input[pivotIndex])){if (i==highIndex) break;}while (less (input[pivotIndex], input[--j])){if (j==lowIndex) break;}if (i>=j) break;exchange(input, i, j);}exchange(input, pivotIndex, j);return j;}}

3路

Optimized-3Way.png

package basics.sorting.quick;import static basics.shuffle.KnuthShuffle.shuffle;
import static basics.sorting.utils.SortUtils.exchange;
import static basics.sorting.utils.SortUtils.less;public class QuickSort3Way {public void sort (int[] input){//input=shuffle(input);sort (input, 0, input.length-1);}public void sort(int[] input, int lowIndex, int highIndex) {if (highIndex<=lowIndex) return;int lt=lowIndex;int gt=highIndex;int i=lowIndex+1;int pivotIndex=lowIndex;int pivotValue=input[pivotIndex];while (i<=gt){if (less(input[i],pivotValue)){exchange(input, i++, lt++);}else if (less (pivotValue, input[i])){exchange(input, i, gt--);}else{i++;}}sort (input, lowIndex, lt-1);sort (input, gt+1, highIndex);}}

双枢轴

Optimized-DualPivot.png

package basics.sorting.quick;import static basics.shuffle.KnuthShuffle.shuffle;
import static basics.sorting.utils.SortUtils.exchange;
import static basics.sorting.utils.SortUtils.less;public class QuickSortDualPivot {public void sort (int[] input){//input=shuffle(input);sort (input, 0, input.length-1);}private void sort(int[] input, int lowIndex, int highIndex) {if (highIndex<=lowIndex) return;int pivot1=input[lowIndex];int pivot2=input[highIndex];if (pivot1>pivot2){exchange(input, lowIndex, highIndex);pivot1=input[lowIndex];pivot2=input[highIndex];//sort(input, lowIndex, highIndex);}else if (pivot1==pivot2){while (pivot1==pivot2 && lowIndex<highIndex){lowIndex++;pivot1=input[lowIndex];}}int i=lowIndex+1;int lt=lowIndex+1;int gt=highIndex-1;while (i<=gt){if (less(input[i], pivot1)){exchange(input, i++, lt++);}else if (less(pivot2, input[i])){exchange(input, i, gt--);}else{i++;}}exchange(input, lowIndex, --lt);exchange(input, highIndex, ++gt);sort(input, lowIndex, lt-1);sort (input, lt+1, gt-1);sort(input, gt+1, highIndex);}}

参考:快速 分拣–来自我们JCG合作伙伴 Arun Manivannan的3向和双向枢轴 ,位于Rerun.me博客上。

翻译自: https://www.javacodegeeks.com/2013/06/quicksorting-3-way-and-dual-pivot.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在jekyll模板博客中添加网易云模块

最近使用GitHub Pages Jekyll 搭建了个人博客&#xff0c;作为一名重度音乐患者&#xff0c;博客里面可以不配图&#xff0c;但是不能不配音乐啊。 遂在博客里面引入了网易云模块&#xff0c;这里要感谢网易云的分享机制&#xff0c;对开发者非常友好&#xff1a; 1.每首歌曲…

线性规划对偶原理

留坑啊留坑。。 白天老师讲的都没听说过 晚上肯定整理不玩啊&#xff0c;&#xff0c;&#xff0c; 转载于:https://www.cnblogs.com/zwfymqz/p/8253842.html

java 18.9_Oracle: Java 11 (18.9 LTS) 正式上线!

美国时间9月25日&#xff0c;Oracle 官方表示&#xff0c; Java 11 (18.9 LTS) 正式上线!这是自 Java 8 后的第一个长期支持版本。Java 11 版本说明按照 Oracle 公布的支持路线图&#xff0c;Java 11 将会获得 Oracle 提供的长期支持服务&#xff0c;直至2026年9月。为了更快地…

CSS3新特性应用之用户体验

目录 背景与边框第一部分背景与边框第二部分形状视觉效果字体排印用户体验结构与布局过渡与动画源码下载 一、光标 新增加not-allowed光标&#xff0c;不允许访问隐藏光标&#xff0c;在触模应用上很有用&#xff0c;css2.1需要一个透明的图片来实现&#xff0c;而css3直接用…

day 60 Bootstrip学习

图标地址 http://fontawesome.io/icons/ 图标用法地址 http://fontawesome.io/examples/ 实现代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"I…

谈谈常用清除浮动的方法

我们在做页面布局的时候&#xff0c;经常需要利用浮动来实现一些布局效果&#xff0c;这样带来的后果就会导致父元素丢失宽度。今天我们就来说说‘找回‘宽度的方法。 而清除浮动后的效果应该是这样的请看&#xff1a; 下面就说说方法&#xff0c;方法其实有非常的多&#xf…

ArcGIS API For JS之网络分析(临近设施分析)

ArcGIS 提供两种网络分析&#xff0c;即基于Geometric Network的有向网络或者设施网络和基于Network Dataset的无向网络&#xff0c;在这里网络的分析指后者&#xff0c;ArcGIS api支持网络分析中的最短路径分析、服务区分析、临近设施分析。本文主要讲的是临近设施分析&#x…

UWP DEP0700: 应用程序注册失败。[0x80073CF9] 另一个用户已安装此应用的未打包版本。当前用户无法将该版本替换为打包版本。...

最近电脑抽风&#xff0c;我在【应用程序和功能】中重置了以下我的App自然灾害&#xff0c;居然&#xff0c;搞出大新闻了。 它居然从列表中消失了。。。 vs再次编译代码的时候&#xff0c;提示 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 DEP…

泽西岛的RESTful Web服务

我已经讨论了有关体系结构注意事项<< link >>的早期文章&#xff0c;以成为可在我的系统/机器上使用的分布式环境上的RESTful系统。 本文我们将讨论如何基于REST体系结构考虑来构建Web服务。 本教程说明了如何使用Tomcat 6&#xff0c;Eclipse和Jersey JAX-RS&…

css水平垂直居中(绝对定位居中)

使用绝对定位有个限制就是父集必须设置一个固定的高度。 首先HTML 1 <div id"box"> 2 <div class"child"></div> 3 </div> CSS 1 #box {2 position: relative;3 height: 500px;4 background: red;5 }6 .chil…

洛谷 2719 搞笑世界杯

洛谷 2719 搞笑世界杯 洛谷原题链接 这道难度只有普及-的题目却花了我一个多小时才搞出来。但做出来之后就会发现&#xff1a;其实这题确实挺水。。。 解题思路&#xff1a; 首先开二维数组 dp [ i ] [ j ] . 代表已售 i 张 A , j 张 B 时后两人买到的票相同的概率。 很显然&am…

搭建SSH框架–使用篇

创建如下包&#xff1a; action用于响应请求 service则是提供请求的操作 dao用于操作数据库 entity用于映射数据库表 打开DB Browser –> personalCD&#xff08;创建篇的数据库连接&#xff09;–> SCOTT –> TABLE –> t_USER –> 右键Hibernate Reverse……

3个简单步骤即可测试Java 8

即将发布的Java 8版本为Java开发人员带来了许多新功能&#xff0c;但是升级时始终存在代码破裂的风险。 我们都记得Java 7发行时有一系列非常严重的错误 。 当然&#xff0c;我们所有人都可以帮助避免在Java 8中出现相同的问题。我今天要介绍的方法是使用现有的Continuous Int…

父类div高度适应子类div

父类div高度适应子类div 通常有许多div的高度由子类的高度决定父类的高度&#xff0c;所以需要父类div要适应子类div的高度&#xff0c;一般情况父类的高度可以直接设置成“auto”即可。 在有的情况下&#xff0c;子类div会撑破父类div. 所以需要走一些调整。通常有3种方法对…

jenkins jar包上传maven仓库

1 Jenkins 编译后部署至 Maven 仓库jenkins编译后构件&#xff08;如&#xff1a;jar包&#xff09;部署至maven仓库需修改以下内容&#xff1a;maven 仓库配置&#xff1b;项目 pom 文件&#xff1b;本地仓库的 settings.xml 内容&#xff1b;jenkins goals 修改1&#x…

Java文件合并变得语义化

与任何程序员交谈&#xff0c;并询问他应该如何进行合并&#xff1a;“它应该理解代码&#xff0c;对其进行解析&#xff0c;然后根据结构进行合并” –他很可能会说。 而这恰恰是SemanticMerge for Java所做的&#xff1a;它解析要合并的文件&#xff08;加上祖先或“文件在更…

KnockoutJS-快速入门

虽然在WPF中接触过MVVM模式&#xff0c;可是刚开始在Web中接触到Knockout.JS让我大吃一惊&#xff0c;简化了好多工作量&#xff0c;原来可能需要一大堆的JS脚本完成的工作量&#xff0c;被释放许多。接触KnockoutJS一年多了&#xff0c;在好多个项目中也用到过&#xff0c;虽然…

如何在一个页面添加多个不同的kindeditor编辑器

kindeditor官方下载地址&#xff1a;http://kindeditor.net/down.php &#xff08;入门必看&#xff09;kindeditor官方文档&#xff1a;http://kindeditor.net/doc.php &#xff08;入门必看&#xff09;Kindeditor编辑器初始化参数文档&#xff1a;http://kindeditor.net/doc…

JSONArray.fromObject不执行且不报错问题的解决

今天在写javaweb工程的时候需要向前台传json格式的数据&#xff0c;用到了json-lib-2.4-jdk15.jar等一系列包&#xff0c;然而却出现如下状况&#xff1a; CityBean是一个javaBean&#xff0c;我们看到&#xff0c;控制台只打印出了list的内容&#xff0c;而下面的两个却没能打…

爬虫-scrapy

阅读目录 一 介绍二 安装三 命令行工具四 项目结构以及爬虫应用简介 五 Spiders六 Selectors七 Items八 Item Pipeline九 Dowloader Middeware十 Spider Middleware十一 settings.py十二 爬取亚马逊商品信息一 介绍 Scrapy一个开源和协作的框架&#xff0c;其最初是为了页面抓取…