Java Arrays.sort源代码解析

来源:互联网 发布:中经商品交易中心软件 编辑:程序博客网 时间:2024/05/16 11:00

基本类型:采用调优的快速排序(Primitive(int,float等原型数据));

对象类型:采用改进的归并排序(Object对象数组)。

源码中选择划分元的方法:

    当数组大小为 size=7 时 ,取数组中间元素作为划分元。int n=m>>1;(此方法值得借鉴)

    当数组大小7< size<=40时,取首、中、末三个元素中间大小的元素作为划分元。

    当数组大小 size>40 时 ,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。

根据划分元 v ,形成不变式 v* (v)* v*

  普通的快速排序算法,经过一次划分后,将划分元排到素组较中间的位置,左边的元素小于划分元,右边的元素大于划分元,而没有将与划分元相等的元素放在其附近,这一点,在Arrays.sort()中得到了较大的优化。

  举例:15、93、15、41、6、15、22、7、15、20

  因 7

  经过一次换分后: 15、15、7、6、41、20、22、93、15、15. 与划分元相等的元素都移到了素组的两边。

  接下来将与划分元相等的元素移到数组中间来,形成:7、6、15、15、15、15、41、20、22、93.

  最后递归对两个区间进行排序[7、6]和[41、20、22、93]. 
  

  1. package com.util;
  2. import java.lang.reflect.Array;
  3. publicclassArraysObject{
  4. privatestaticfinalint INSERTIONSORT_THRESHOLD=7;
  5. privateArraysObject(){}
  6. publicstaticvoid sort(Object[] a){
  7. //java.lang.Object.clone(),理解深表复制和浅表复制
  8. Object[] aux =(Object[]) a.clone();
  9. mergeSort(aux, a,0, a.length,0);
  10. }
  11. publicstaticvoid sort(Object[] a,int fromIndex,int toIndex){
  12. rangeCheck(a.length, fromIndex, toIndex);
  13. Object[] aux = copyOfRange(a, fromIndex, toIndex);
  14. mergeSort(aux, a, fromIndex, toIndex,-fromIndex);
  15. }
  16. /**
  17. * Src is the source array that starts at index 0
  18. * Dest is the (possibly larger) array destination with a possible offset
  19. * low is the index in dest to start sorting
  20. * high is the end index in dest to end sorting
  21. * off is the offset to generate corresponding low, high in src
  22. */
  23. privatestaticvoid mergeSort(Object[] src,Object[] dest,int low,
  24. int high,int off){
  25. int length = high- low;
  26. // Insertion sort on smallest arrays
  27. if(length< INSERTIONSORT_THRESHOLD){
  28. for(int i= low; i< high; i++)
  29. for(int j= i; j> low&&
  30. ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
  31. swap(dest, j, j-1);
  32. return;
  33. }
  34. // Recursively sort halves of dest into src
  35. int destLow = low;
  36. int destHigh = high;
  37. low+= off;
  38. high+= off;
  39. /*
  40. * >>>:无符号右移运算符
  41. * expression1 >>> expresion2:expression1的各个位向右移expression2
  42. * 指定的位数。右移后左边空出的位数用0来填充。移出右边的位被丢弃。
  43. * 例如:-14>>>2; 结果为:1073741820
  44. */
  45. int mid =(low+ high)>>>1;
  46. mergeSort(dest, src, low, mid,-off);
  47. mergeSort(dest, src, mid, high,-off);
  48. // If list is already sorted, just copy from src to dest. This is an
  49. // optimization that results in faster sorts for nearly ordered lists.
  50. if(((Comparable) src[mid-1]).compareTo(src[mid])<=0){
  51. System.arraycopy(src, low, dest, destLow, length);
  52. return;
  53. }
  54. // Merge sorted halves (now in src) into dest
  55. for(int i= destLow, p= low, q= mid; i< destHigh; i++){
  56. if(q>= high|| p< mid
  57. &&((Comparable) src[p]).compareTo(src[q])<=0)
  58. dest[i]= src[p++];
  59. else
  60. dest[i]= src[q++];
  61. }
  62. }
  63. /**
  64. * Check that fromIndex and toIndex are in range, and throw an appropriate
  65. * exception if they aren't.
  66. */
  67. privatestaticvoid rangeCheck(int arrayLen,int fromIndex,int toIndex){
  68. if(fromIndex> toIndex)
  69. thrownewIllegalArgumentException("fromIndex("+ fromIndex
  70. +") > toIndex("+ toIndex+")");
  71. if(fromIndex<0)
  72. thrownewArrayIndexOutOfBoundsException(fromIndex);
  73. if(toIndex> arrayLen)
  74. thrownewArrayIndexOutOfBoundsException(toIndex);
  75. }
  76. publicstatic<T> T[] copyOfRange(T[] original,int from,int to){
  77. return copyOfRange(original, from, to,(Class<T[]>) original.getClass());
  78. }
  79. publicstatic<T, U> T[] copyOfRange(U[] original,int from,int to,
  80. Class<?extends T[]> newType){
  81. int newLength = to- from;
  82. if(newLength<0)
  83. thrownewIllegalArgumentException(from+" > "+ to);
  84. T[] copy =((Object) newType==(Object)Object[].class)
  85. ?(T[])newObject[newLength]
  86. :(T[])Array.newInstance(newType.getComponentType(), newLength);
  87. System.arraycopy(original, from, copy,0,
  88. Math.min(original.length- from, newLength));
  89. return copy;
  90. }
  91. /**
  92. * Swaps x[a] with x[b].
  93. */
  94. privatestaticvoid swap(Object[] x,int a,int b){
  95. Object t = x[a];
  96. x[a]= x[b];
  97. x[b]= t;
  98. }
  99. }

对于Object类型源码分析如下

  1. package com.util;
  2. import java.lang.reflect.Array;
  3. publicclassArraysObject{
  4. privatestaticfinalint INSERTIONSORT_THRESHOLD=7;
  5. privateArraysObject(){}
  6. publicstaticvoid sort(Object[] a){
  7. //java.lang.Object.clone(),理解深表复制和浅表复制
  8. Object[] aux =(Object[]) a.clone();
  9. mergeSort(aux, a,0, a.length,0);
  10. }
  11. publicstaticvoid sort(Object[] a,int fromIndex,int toIndex){
  12. rangeCheck(a.length, fromIndex, toIndex);
  13. Object[] aux = copyOfRange(a, fromIndex, toIndex);
  14. mergeSort(aux, a, fromIndex, toIndex,-fromIndex);
  15. }
  16. /**
  17. * Src is the source array that starts at index 0
  18. * Dest is the (possibly larger) array destination with a possible offset
  19. * low is the index in dest to start sorting
  20. * high is the end index in dest to end sorting
  21. * off is the offset to generate corresponding low, high in src
  22. */
  23. privatestaticvoid mergeSort(Object[] src,Object[] dest,int low,
  24. int high,int off){
  25. int length = high- low;
  26. // Insertion sort on smallest arrays
  27. if(length< INSERTIONSORT_THRESHOLD){
  28. for(int i= low; i< high; i++)
  29. for(int j= i; j> low&&
  30. ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
  31. swap(dest, j, j-1);
  32. return;
  33. }
  34. // Recursively sort halves of dest into src
  35. int destLow = low;
  36. int destHigh = high;
  37. low+= off;
  38. high+= off;
  39. /*
  40. * >>>:无符号右移运算符
  41. * expression1 >>> expresion2:expression1的各个位向右移expression2
  42. * 指定的位数。右移后左边空出的位数用0来填充。移出右边的位被丢弃。
  43. * 例如:-14>>>2; 结果为:1073741820
  44. */
  45. int mid =(low+ high)>>>1;
  46. mergeSort(dest, src, low, mid,-off);
  47. mergeSort(dest, src, mid, high,-off);
  48. // If list is already sorted, just copy from src to dest. This is an
  49. // optimization that results in faster sorts for nearly ordered lists.
  50. if(((Comparable) src[mid-1]).compareTo(src[mid])<=0){
  51. System.arraycopy(src, low, dest, destLow, length);
  52. return;
  53. }
  54. // Merge sorted halves (now in src) into dest
  55. for(int i= destLow, p= low, q= mid; i< destHigh; i++){
  56. if(q>= high|| p< mid
  57. &&((Comparable) src[p]).compareTo(src[q])<=0)
  58. dest[i]= src[p++];
  59. else
  60. dest[i]= src[q++];
  61. }
  62. }
  63. /**
  64. * Check that fromIndex and toIndex are in range, and throw an appropriate
  65. * exception if they aren't.
  66. */
  67. privatestaticvoid rangeCheck(int arrayLen,int fromIndex,int toIndex){
  68. if(fromIndex> toIndex)
  69. thrownewIllegalArgumentException("fromIndex("+ fromIndex
  70. +") > toIndex("+ toIndex+")");
  71. if(fromIndex<0)
  72. thrownewArrayIndexOutOfBoundsException(fromIndex);
  73. if(toIndex> arrayLen)
  74. thrownewArrayIndexOutOfBoundsException(toIndex);
  75. }
  76. publicstatic<T> T[] copyOfRange(T[] original,int from,int to){
  77. return copyOfRange(original, from, to,(Class<T[]>) original.getClass());
  78. }
  79. publicstatic<T, U> T[] copyOfRange(U[] original,int from,int to,
  80. Class<?extends T[]> newType){
  81. int newLength = to- from;
  82. if(newLength<0)
  83. thrownewIllegalArgumentException(from+" > "+ to);
  84. T[] copy =((Object) newType==(Object)Object[].class)
  85. ?(T[])newObject[newLength]
  86. :(T[])Array.newInstance(newType.getComponentType(), newLength);
  87. System.arraycopy(original, from, copy,0,
  88. Math.min(original.length- from, newLength));
  89. return copy;
  90. }
  91. /**
  92. * Swaps x[a] with x[b].
  93. */
  94. privatestaticvoid swap(Object[] x,int a,int b){
  95. Object t = x[a];
  96. x[a]= x[b];
  97. x[b]= t;
  98. }
  99. }
原创粉丝点击