欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

快速分类–三向和双枢轴

发布时间:2023/12/3 57 豆豆
生活随笔 收集整理的这篇文章主要介绍了 快速分类–三向和双枢轴 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

毫无疑问,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)的实现

单枢轴

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路

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);}}

双枢轴

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

总结

以上是生活随笔为你收集整理的快速分类–三向和双枢轴的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。