Java Arrays.sort Source Code parsing

Source: Internet
Author: User
Tags array length comparable shallow copy sorts

Premise:

When using Scala's Sortwith, discover:

def sortwith (LT: (A, a) ? Boolean): List[a] //A is a list element type

Sort by the specified comparison function LT, and the ordering is stable,

Ultimately, essentially, the call to Java.util.Arrays.sort is ordered.

Eg: List(1,-3, 4, 2, 6) Sortwith (_ < _)//res48:list[int] = List ( -3, 1, 2, 4, 6)

Therefore, to go to understand the method of Java.util.Arrays.sort, online cleaning, see the following write good, moved here for study.

 Sorting for all types is available in Java arrays. It is mainly divided into primitive (8 kinds of basic types) and object two major categories.

Basic types: fast sorting with tuning;

Object type: An improved merge sort is used.

First, the basic type of source code analysis is as follows (in int[] for example):

Java uses a quick sort of array of primitive (Int,float and other prototype data) to sort the array of object objects by merging. for this distinction, Sun's explanations in <<the Java tutorial>> are as follows:

The sort operation uses a slightly optimized merge sort algorithm that's fast and stable:

* Fast:it is guaranteed-to-run in N-log (n) time and runs substantially faster on nearly sorted lists. Empirical tests showed it to is as fast as a highly optimized quicksort. A quicksort is generally considered to being faster than a merge sort but isn ' t stable and doesn ' t guarantee n log (n) perform Ance.

* Stable:it doesn ' t reorder equal elements. This is important if you sort the same list repeatedly on different attributes. If a user of a mail program sorts the Inbox by mailing date and then sorts it by sender, the user naturally expects that T He now-contiguous list of messages from a given sender would (still) be sorted by mailing date. This is guaranteed only if the second sort was stable.

In other words, the optimized merge sort is fast (Nlog (n)) and stable.

for the ordering of objects, stability is important. such as the report card, the beginning may be according to the number of people in the order of the line, and now let us use scores platoon, then you should ensure that the original Zhang San in front of John Doe, even if their results are the same, Zhang San can not run to the back of John Doe.

The fast sort is unstable, and the worst-case time complexity is O (n^2).

In addition, the object array is only a reference to the object, so multiple shifts do not cause additional overhead, but the object array is generally more sensitive to the comparison, it is possible that the comparison of the object is much more expensive than the simple number. Merge sort is better than fast sorting in this respect, which is one of the important reasons to choose it as an object sort.

  Sorting optimization: The implementation of the fast and merge are recursive, and at the bottom of the recursion, that is, the array length to be sorted is less than 7 o'clock, the direct use of bubble sort, and no longer recursive.

Analysis: An array of length 6 bubble sort the total number of comparisons is 1+2+3+4+5+6=21 times, preferably only 6 times compared. The overhead of a quick row or merge involves recursive invocation, and its time efficiency is highlighted at the lesser of N, so a bubbling sort is used, which is an extremely important optimization for fast sequencing.

The rapid sequencing in the source code, mainly to do the following several aspects of optimization:

1) When the number of elements in the array to be sorted is small, the threshold value in the source code is 7, and the insertion sort is used. while insertion sorting has a time complexity of 0 (n^2), insertion sorting is preferable to fast sorting when there are fewer array elements, because recursive operations that quickly sort affect performance.

2) better selection of the partition element (datum element). The ability to divide an array into roughly two equal parts avoids the worst case scenario. For example, when the array is ordered, selecting the first element as the partition element will make the time complexity of the algorithm reach O (n^2).

The method of selecting the partition element in the source code:

When the array size is size=7, the middle element of the array is taken as the dividing element. int n=m>>1; (This method is worth learning)

When the size of the array is 7<size<=40, the elements of the middle size of the first, middle, and last three elements are taken as the dividing element.

When the size of the array is size>40, select 9 elements from the array to be spaced evenly, and choose a pseudo-median as the dividing element.

3) According to the division of the V, the formation of the invariant v* (<v) * (>v) * v*

  Ordinary fast sorting algorithm, after a division, will be divided into the middle of the group of elements, the left element is less than the partition element, the right element is greater than the partition element, and not the element equal to the partition is placed near it, this, in the Arrays.sort () has been greatly optimized.

Examples: 15, 93, 15, 41, 6, 15, 22, 7, 15, 20

Because of 7<size<=40, select v = 15 as the dividing element in 15, 6, and 20.

After a break: 15, 15, 7, 6, 41, 20, 22, 93, 15, 15. Elements equal to the dividing element are moved to both sides of the group.

The next step is to move the elements equal to the element into the middle of the array, forming: 7, 6, 15, 15, 15, 15, 41, 20, 22, 93.

Finally, the two intervals are sorted by recursion [7, 6] and [41, 20, 22, 93].

  Part of the source code (a) is as follows:

  1 package com.util;  2 3 public class Arraysprimitive {4 private arraysprimitive () {} 5 6/** 7 * Sorts the specified array of type int in ascending order of numbers.      8 */9 public static void sort (int[] a) {Sort1 (A, 0, a.length); 11} 12 13/** 14 * The specified range for the specified array of type int is sorted in ascending order of numbers. * * * public static void sort (int[] A, int fromIndex, int toindex) {Rangecheck (a.length, FromIndex , Toindex); Sort1 (A, FromIndex, Toindex-fromindex); \ sort1 (int x[], int off, int len) {22/* 23 * When the number of elements in the array to be sorted is less than 7 o'clock , using insert sort. 24 * 25 * Although insertion sequencing has a time complexity of O (n^2), insertion sorting is better than fast sorting when there are fewer elements in the array, because recursive operations that quickly sort affect performance.  + * IF (Len < 7) {(int i = off; I < Len + off; i++) (int j = i; j > off && x[j-1] > X[j]; j--) swap (x, J, j-1); return; 32} 33/* 34 * When the number to be sortedThe number of elements in a group is greater than or equal to 7 o'clock, with a quick sort. * Choose a partition element, v 37 * Select a partition element, v 38 * 39 * Good choice of partition element ( Datum elements). The ability to divide an array into roughly two equal parts avoids the worst case scenario. For example, when an array is ordered, 40 * selects the first element as the partition element, which will make the algorithm's time complexity reach O (n^2). 41 */42//When the array size is size=7, the middle element of the array is taken as the dividing element. int m = off + (len >> 1); 44//When the array size is 7<size<=40, the elements of the middle size of the first, middle, and last three elements are taken as the dividing element.              if (Len > 7) {len-1 int l = off; int n = off + +; 48/* 49 * When the size of the array is size>40, select 9 elements from the array to be lined up evenly, 50 * Choose a pseudo-median as the dividing element.  * * * if (len > +) {len/8 int s = n, L = med3 (x, L, L + S, L + 2 * s); m = med3 (x, M-s, M, M + s); A. N = med3 (x, n-2 * s, N-N.); 57} 58//Remove the position of the middle-sized element. m = med3 (x, L, M, N); Mid-size, Med of 3 60} 61 62//To the dividing element V (int v = x[m];  +//Establish invariant:v* (<v) * (>v) * v* int a = off, B = A, c = off + len-1, D = C;                     70 while (true) {<= (b-C && x[b] <= v) {if (x[b] = =) Swap (x, a++, b); b++;                     (c >= b && x[c] >= v) {X[c] = = v) 75 Swap (x, C, d--); c--; (b > C); (x, b++, c--); Bayi}//Swap partition elements back to middle with an int s, n = off + len; s = math.min (A-off, b-a); Vecswap (x, Off, B-s, s); s = math.min (D-c, n-d-1); Vecswap (x, B, n-s); Recursively sort non-partition-elements if ((s = b-a) > 1) sort1 (x, off, s); if ((s = d-c) > 1) sort1 (x, n-s); 94/** * Swaps X[a] with x[b].         * */98 private static void swap (int x[], int a, int b) {in-the-int t = x[a];100 X[a] = x[b];101 X[B] = t;102}103 104/**105 * Swaps x[a. (a+n-1)] With X[b. (b+n-1)]. 106 */107 private static void Vecswap (int x[], int A, int b, int n) {108 for (int i=0; i<n; i++, a++, b++) 109 Swap (x, a, b);}111/**113 * Returns The index of the median of the three indexed gers.114 */115 private static int med3 (int x[], int A, int B, int. c) {$ return (X[a] < x[b]?     (X[b] < X[c]? B:x[a] < X[c]? c:a) 117: (X[b] > X[c]? b:x[a] > X[c]? c:a)); 118 }119/**121 * Check that FromIndex and Toindex is in range, and throw an122 * appropriate exception if They aren ' t.123 */124 private staticvoid Rangecheck (int arraylen, int fromIndex, int toindex) {(FromIndex > Toindex) 126 throw NE         W illegalargumentexception ("FromIndex (" + fromIndex127 + ") > Toindex (" + Toindex + ")"); 128 if (FromIndex < 0) 129 throw new ArrayIndexOutOfBoundsException (FromIndex), if (Toindex > AR Raylen) 131 throw new ArrayIndexOutOfBoundsException (Toindex); 132}133}

  The test code is as follows:

1 package com.test; 2  3 import com.util.ArraysPrimitive; 4  5 public class Arraystest {6 public     static void Main (string[] args) { 7         int [] a={15,93,15,41,6,15,22,7,15,20}; 8         arraysprimitive.sort (a); 9 for         (int i=0;i<a.length;i++) { Ten             System.out.print (a[i]+ ",");         }12         //Result: 6,7,15,15,15,15,20,22,41,93,13     }14}

Second, for the object type source code analysis is as follows:

  Part of the source code (ii) is as follows:

  1 package com.util;  2 3 Import Java.lang.reflect.Array;  4 5 public class Arraysobject {6 private static final int insertionsort_threshold = 7; 7 8 Private Arraysobject () {} 9 public static void sort (object[] a) {//java.lang.object.clone () , understand deep table copy and shallow copy object[] aux = (object[]) a.clone (); MergeSort (aux, A, 0, a.length, 0); + public static void sort (object[] A, int fromIndex, int. toindex) {Rangecheck (a.length, from Index, Toindex); object[] aux = Copyofrange (A, FromIndex, Toindex); MergeSort (aux, A, FromIndex, Toindex,-fromindex); /** * SRC is the source array, starts at index 0 * Dest is the (possibly larger) Array destination with a possible offset (* low) is the index of dest to start sorting-high-is the end I    Ndex in dest to end sorting * off are the offset to generate corresponding low, high in SRC 28  */private static void MergeSort (object[] src, object[] dest, int low, int. high, int off) {31 int length = high-low; +//insertion sort on smallest arrays if (length < Insertionsort_threshold) {F or (int i = low, i < high; i++)-(int j = i; j > Low && 37 ( Comparable) (Dest[j-1]). CompareTo (Dest[j]) > 0; j--) (dest, J, J-1); The return; +//Recursively sort halves of dest into src + int destlow = low; Desthigh int = high; Low + = off; + + + off; */* &GT;&GT;&GT;: Unsigned right-shift operator * Expression1 >>> expresion2:expression1 Each bit move right ex Pression2 50 * The number of digits specified. The number of left-vacated digits after the right shift is filled with zeros. Move out the right bit is discarded. 51 * For example:-14>>>2; results are: 1073741820 */Int. INT MID = (low + high) >>> 1; 54 mergesort (dest, SRC, Low, Mid,-off); MergeSort (dest, SRC, Mid, High,-off); Already/If list is sorted, just copy from Src to dest. This was an optimization///-results in faster sorts for nearly ordered lists. (((comparable) src[mid-1]). CompareTo (Src[mid]) <= 0) {system.arraycopy (src, low, dest, Destlow, length); The return; +//Merge sorted halves (now in SRC) to dest (int i = destlow, p = low, q = mi D i < Desthigh; i++) {if (q >= High | | P < MID && ((comparable) src[p]). CompareTo (src [Q]) <= 0) Dest[i] = src[p++]; [else] dest[i] = src[q++];      /** * Check that FromIndex and Toindex is in range, and throw a appropriate 76 * exception if they aren ' t. * * +/-private static void rangecheck (int arraylen, int fromIndex, int toindex) {if (FromIndex > Toindex) throw new illegal ArgumentException ("FromIndex (" + FromIndex Bay + ") > Toindex (" + Toindex + ")"); if (FromIndex < 0) The new arrayindexoutofboundsexception (FromIndex); if (Toindex > Arraylen)-throw new ArrayIndexOutOfBoundsException (Toindex); (t[) Copyofrange (t[] original, int from, int to) {Copyofrang E (original, From, to, (class<t[]>) Original.getclass ()); <t, u> t[] Copyofrange (u[] original, int from, int. to, Class<? e Xtends t[]> newType) {94 int newlength = To-from; if (Newlength < 0) # throw new IllegalArgumentException (from + ' > ' + to); t[] Copy = ((object) NewType = = (object) object[].class) 98? (t[] New Object[newlength]: (t[]) array.newinstance (Newtype.getcomponenttype (), newlength); Ystem.arraycopy (original, from, copy, 0,101 math.min (Original.length-from, Newlength)); 102 Retur  n copy;103}104/**106 * Swaps X[a] with x[b].107 */108 private static void Swap (object[] x, int A, int b) {109 Object t = x[a];110 x[a] = x[b];111 X[b] = t;112}113}

  The test code is as follows:

 1 package com.test; 2 3 Import Com.util.ArraysObject; 4 5 public class Arraysobjectsorttest {6 public static void main (string[] args) {7 Student stu1=new Student (1001,100.0f); 8 Student stu2=new Student (1002,90.0f); 9 Student stu3=new Student (1003,90.0f); Student stu4=new Student (1004,95.0f); student[] stus={ Stu1,stu2,stu3,stu4};12//arrays.sort (Stus); Arraysobject.sort (Stus), + for (int i=0;i<stus.le ngth;i++) {System.out.println (Stus[i].getid () + ":" +stus[i].getscore ()); 16}17/* 1002:90. 018 * 1003:90.019 * 1004:95.020 * 1001:100.021 */22}23}24 class Student im  plements comparable<student>{25 private int id;  Study number: private float score; Grade Student () {}28 public Student (int id,float score) {this.id=id;30 this.score=score;3 1}32 @Override33 public int compareTo (StudenT s) {return (int) (This.score-s.getscore ());}36 public int getId () {PNS return id;38}39     public void SetId (Int. id) {this.id = id;41}42 public float Getscore () {score;44 }45 public void SetScore (float score) {This.score = score;47}48}

  Auxiliary Understanding Code:

1 package Com.lang; 2  3 Public final class System {4     //system class cannot be instantiated.  5     Private System () {} 6     //In the facilities provided by the system class, there are standard input, standard output and error output streams, access to externally defined Properties 7     //and environment variables; methods for loading files and libraries And a practical way to quickly copy part of an array. 8     /** 9      * src and dest must be of the same type or an array of types that can be converted. Ten      * @param      src the      source array.11      * @param      srcpos   starting position in the source array.12      * @param      dest The     destination array.13      * @param      destpos  starting position in The destination data.14      * @param length The number of the      array elements to be   copied.15      */16     public static native void Arraycopy (object src, int srcpos, object dest,17             int destpos, int length); 18}
1 package com.lang.reflect; 2  3 Public final class array {4     private array () {} 5      6     //Create a new array with the specified component type and dimension. 7 public     static Object newinstance (class<?> componenttype, int length) 8             throws negativearraysizeexception {9         return NewArray (componenttype, length),     }11,     private static native Object NewArray (Class componenttype, int length)             throws negativearraysizeexception;14}

Reference: https://www.cnblogs.com/gw811/archive/2012/10/04/2711746.html

Java Arrays.sort Source Code parsing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.