时间:2021-05-20
这里描述 leftmost = true 的情况,也就是会从数组的开始一直排序到数组的结尾。
数组类型:int[]、long[]、short[]、char[]、float[]、double[],还有比较特殊的 byte[]
适合长度短的数组排序,对于byte[] 长度小于等于30 和 其它数组长度小于47 的情况,会使用这种排序
代码以 int[] a 为例:
// 第一次循环i=j=0,之后每次循环j=i.// j = ++i相当于在每次循环的最后执行 {i++; j = i;}// j = i++相当于在每次循环的最后执行 {j = i; i++;}for (int i = 0, j = i; i < (length - 1); j = ++i) { int ai = a[i + 1]; // 每次循环的目的是将下一个数排到它应该在的位置,这里ai就是下一个数 while (ai < a[j]) { // while循环的目的是确定j的值 和 把所有比ai大的项向后移一位来腾出ai的位置 a[j + 1] = a[j]; // 把比ai大的项向后移一位 if (j-- == left) { // j-- 确定j的值,也就是确定ai的位置, j 可能等于 -1 break; } } a[j + 1] = ai; // j+1 就是ai的位置}只针对byte[] 长度大于30的情况,因为byte的范围是[-128, 127],只有256个数,所以循环会利用这点
int[] count = new int[256];// 第一次循环:计数for (int i = (0 - 1); ++i <= (length - 1); count[a[i] - (-128)]++);// 第二次循环:给 < byte[] a > 赋值// 循环结束条件以k为标准,k<=0就会停止;// 因为i和k没有固定关系,所以没有增量表达式,但在方法体中利用--i和--k进行增量。for (int i = 256, k = length; k > 0; ) { while (count[--i] == 0); // 如果计数个数为0,什么也不做,--i byte value = (byte) (i + (-128)); int s = count[i]; do { a[--k] = value; } while (--s > 0);}适合长度短的数组排序,插入排序也是快速排序的一种。
对于byte[] 长度大于30的情况会使用 计数排序,不是这种排序。
而对于其它数组长度大于等于47并且小于286 的情况,会使用这种排序。
这种情况会将排序分三块,变量 pivot1 和 pivot2 作为三块区域值的区分:
第一块区域所有的值都 < pivot1
第二块区域所有的值都 >= pivot1 并且 <= pivot2
第三块区域所有的值都 > pivot2
分两种情况:
如果第二块剩余项超过数组要排序总长度的4/7,会将等于pivot1和等于pivot2的值取出来,再次缩减less和great中间的部分,然后进行排序。
否则直接排序。
这种情况也可以理解为将排序分三块,但只需要一个变量 pivot 作为三块区域值的区分:
第一块区域所有的值都 < pivot
第二块区域所有的值都 = pivot,因为这块区域的值都相等,最后就可以不用排序
第三块区域所有的值都 > pivot
长度很长的数组排序,对于其它数组长度大于等于286 的情况,会使用这种排序。
两个关键常量,起控制作用
// 合并排序中的最大运行次数static final int MAX_RUN_COUNT = 67;// 合并排序中运行的最大长度static final int MAX_RUN_LENGTH = 33;排序方法
/** * 长度大于等于286的int数组排序 * * @param a * 要排序int数组 * @param left * 起始下标 * @param right * 结束下标 * @param work * null * @param workBase * 0 * @param workLen * 0 */private static void largeSort(int[] a, int left, int right, int[] work, int workBase, int workLen) { /* * Index run[i] is the start of i-th run (ascending or descending * sequence). */ int[] run = new int[MAX_RUN_COUNT + 1]; int count = 0; run[0] = left; // Check if the array is nearly sorted for (int k = left; k < right; run[count] = k) { if (a[k] < a[k + 1]) { // ascending while (++k <= right && a[k - 1] <= a[k]); } else if (a[k] > a[k + 1]) { // descending while (++k <= right && a[k - 1] >= a[k]); for (int lo = run[count] - 1, hi = k; ++lo < --hi;) { int t = a[lo]; a[lo] = a[hi]; a[hi] = t; } } else { // equal for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k];) { if (--m == 0) { sort(a, left, right, true); return; } } } /* * The array is not highly structured, use Quicksort instead of * merge sort. */ if (++count == MAX_RUN_COUNT) { sort(a, left, right, true); return; } } // Check special cases // Implementation note: variable "right" is increased by 1. if (run[count] == right++) { // The last run contains one element run[++count] = right; } else if (count == 1) { // The array is already sorted return; } // Determine alternation base for merge byte odd = 0; for (int n = 1; (n <<= 1) < count; odd ^= 1); // Use or create temporary array b for merging int[] b; // temp array; alternates with a int ao, bo; // array offsets from 'left' int blen = right - left; // space needed for b if (work == null || workLen < blen || workBase + blen > work.length) { work = new int[blen]; workBase = 0; } if (odd == 0) { System.arraycopy(a, left, work, workBase, blen); b = a; bo = 0; a = work; ao = workBase - left; } else { b = work; ao = 0; bo = workBase - left; } // Merging for (int last; count > 1; count = last) { for (int k = (last = 0) + 2; k <= count; k += 2) { int hi = run[k], mi = run[k - 1]; for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { b[i + bo] = a[p++ + ao]; } else { b[i + bo] = a[q++ + ao]; } } run[++last] = hi; } if ((count & 1) != 0) { for (int i = right, lo = run[count - 1]; --i >= lo; b[i + bo] = a[i + ao] ); run[++last] = right; } int[] t = a; a = b; b = t; int o = ao; ao = bo; bo = o; }}以上就是Java使用DualPivotQuicksort排序的详细内容,更多关于DualPivotQuicksort排序的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
在这个页面上我们将提供java8Streamsorted()示例。我们可以按照自然排序以及Comparator提供的排序对流进行排序。在java8中Compar
正文Java中的对象正常情况下只能进行比较==或者!=不能使用><,但是在实际的开发中,我们需要对多个对象进行排序,就是需要比较对象的大小Java实现对象排序的
本文实现了八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序首先是EightAlgorithms.java文
我们在学习Java的过程中肯定会遇到对数组进行升序或降序等排序问题,本节主要介绍如何实现Java数组的升序和降序。Java语言使用Arrays类提供的sort(
一、概述: 本文给出常见的几种排序算法的原理以及Java实现,包括常见的简单排序和排序算法,以及其他常用的算法知识。简单排序:冒泡排序、选择排序、插入排序排序