Java Common sorting algorithm and performance test set _java

Source: Internet
Author: User
Tags array length arrays reflection advantage

Now go back to understanding, combine your own experience, choose the best way to describe these algorithms, to facilitate understanding of their working principles and programming skills. This article is suitable for doing Java interview Preparation materials reading.

Attach a test report first:

Array length:20000
bubblesort:766 ms
bubblesortadvanced:662 ms
bubblesortadvanced2:647 ms
selectsort:252 ms
insertsort:218 ms
insertsortadvanced:127 ms
insertsortadvanced2:191 ms
Binarytreesort:3 ms
Shellsort:2 ms
Shellsortadvanced:2 ms
Shellsortadvanced2:1 ms
Mergesort:3 ms
Quicksort:1 ms
Heapsort:2 ms

By testing, it can be argued that bubble sort is perfectly justifiable to throw into the dustbin. The only reason it exists is probably the best understanding. Hill sort of efficiency is I did not think of; heap sorting difficult to understand and write, want to have macroscopic thinking.

Copy Code code as follows:



Package algorithm.sort;

Import Java.lang.reflect.Method;
Import Java.util.Arrays;
Import Java.util.Date;

/**


* Java common sorting algorithm and performance test set


*


* This program set covers the compilation of common sorting algorithms, and in the annotation with extremely simple special case explained the work principle of various algorithms, in order to facilitate understanding and absorption;


* In the process of compiling a lot of Wikipedia and other people blog examples, and combine their own thinking, choose and improve one of the most easy to understand the wording


* (especially the quick sort, I think the algorithm I write is best understood).


* Also includes a centralized performance test and correctness test method for easy observation.


* @author/link.php?url=http://blog.csdn.net/sunxing007


* Reprint please indicate from/link.php?url=http://blog.csdn.net/sunxing007


*/


public class Sortutil {


Set of methods being tested


Static string[] Methodnames = new string[]{


"Bubblesort",


"Bubblesortadvanced",


"BubbleSortAdvanced2",


"Selectsort",


"Insertsort",


"Insertsortadvanced",


"InsertSortAdvanced2",


"Binarytreesort",


"Shellsort",


"Shellsortadvanced",


"ShellSortAdvanced2",


"MergeSort",


"QuickSort",


"Heapsort"


};


public static void Main (string[] args) throws exception{


Correctnesstest ();


Performancetest (20000);


}





/**


* Correctness Test <br>


* Simply test the correctness of each algorithm <br>


* Just to make it easy to see if the newly added algorithm is basically correct;<br>


* @throws Exception is mainly reflected by reflection-related exception;<br>


*/


public static void Correctnesstest () throws exception{


int len = 10;


Int[] A = new Int[len];


for (int i=0; i<methodnames.length; i++) {


for (int j=0; j<a.length; j) {


A[J] = (int) Math.floor (math.random () *len*2);


}


Method sortmethod = null;


SortMethod = SortUtil.class.getDeclaredMethod (Methodnames[i], A.getclass ());


Object o = Sortmethod.invoke (null, a);


System.out.print (Methodnames[i] + ":");


if (o==null) {


System.out.println (Arrays.tostring (a));


}


else{


Considering MergeSort, the result of its order appears in the form of return value;


System.out.println (arrays.tostring (int[) o));


}


}


}





/**


* Performance Testing <br>


* Array length is passed with parameter Len, each method runs 20 times the time-consuming average;<br>


* @param len Array length is recommended to take more than 10000, otherwise some algorithms will show time consuming for 0;<br>


* @throws Exception is mainly reflected by reflection-related exception;<br>


*/


public static void Performancetest (int len) throws exception{


Int[] A = new Int[len];


int times = 20;





System.out.println ("Array Length:" + a.length);


for (int i=0; i<methodnames.length; i++) {


Method sortmethod = null;


SortMethod = SortUtil.class.getDeclaredMethod (Methodnames[i], A.getclass ());


int totaltime = 0;


for (int j=0; j<times; j) {


for (int k=0; k<len; k++) {


A[K] = (int) Math.floor (math.random () *20000);


}


Long start = new Date (). GetTime ();


Sortmethod.invoke (null, a);


Long end = new Date (). GetTime ();


TotalTime + = (End-start);


}


System.out.println (Methodnames[i] + ":" + (Totaltime/times) + "MS");


System.out.println (Arrays.tostring (a));


}


}





/**


* The most original bubble exchange sort;<br>


* Two-level traversal, the outer layer control the number of scans, the number of internal control comparisons;<br>


* Every time the outer layer is scanned, one of the largest elements is sunk; so the inner-layer comparison will gradually decrease;<br>


*/


public static void Bubblesort (int[] a) {


for (int i=0; i<a.length; i++) {


for (int j=0; j<a.length-i-1; j) {


if (A[j]>a[j+1]) {


int tmp = A[J];


A[J] = a[j+1];


A[J+1] = tmp;


}


}


}


}





/**


* Improved Bubbling Method <br>


* The improvement lies in: To set a sign bit, if a trip ran down, there is no exchange, the description has been lined up;<br>


*/


public static void Bubblesortadvanced (int[] a) {


int k = a.length-1;


Boolean flag = true;


while (flag) {


Flag = false;


for (int i=0;i<k;i++) {


if (A[i]>a[i+1]) {


int tmp = A[i];


A[i] = a[i+1];


A[I+1] = tmp;


If there is an exchange, continue to maintain the mark position;


Flag = true;


}


}


k--;


}


}





/**


* Improved Bubbling Method 2<br>


* The improvement is to absorb the above ideas (no exchange means already orderly), if the local is already orderly, then the subsequent comparisons do not need to compare them. <br>


* For example: 3142 5678, if just finished 2 and 4 exchange, found that this trip has not been exchanged, then the subsequent comparison only need to be compared to 4 can;<br>


* The algorithm is to use a flag bit to record the last occurrence of a trip to the location;<br>


*/


public static void BubbleSortAdvanced2 (int[] a) {


int flag = a.length-1;


int k;


while (flag>0) {


k = Flag;


Flag = 0;


for (int i=0; i<k; i++) {


if (A[i] > a[i+1]) {


int tmp = A[i];


A[i] = a[i+1];


A[I+1] = tmp;


Where an exchange is recorded, the place where the last occurrence of the trip is compared;


flag = i+1;


}


}


}


}





/**


* Insert Sort


*


* About the insertion sort, here are a few conventions to quickly understand the algorithm:<br>


* I: Unordered table traversal subscript;i<n-1;<br>


* J: Ordered table traversal following table;0<=j<i;<br>


* A[i]: Represents an unordered header element that is currently being taken out to do an insert sort;<br>


* A[j]: Any element in an ordered table;<br>


* <br>


* Algorithm key point: The array is divided into a[0~i-1] ordered table, a[i~n-1] unordered table, each time from the unordered table head to take a,<br>


* Insert it into the proper position of the ordered table until the unordered table is empty;<br>


* Initial, a[0] is ordered table, a[1~n-1] is unordered table;<br>


*/


public static void Insertsort (int[] a) {


Start traversal from unordered table headers;


for (int i=1; i<a.length; i++) {


Int J;


Take A[i] and ordered table elements in order to compare, find a proper position;


for (j=i-1;j>=0; j--) {


if (A[j] < a[i]) {


Break


}


}


If the appropriate position is found, start from that position, move the element back one space, and make room for the inserted element;


if (j!= (i-1)) {


int tmp = A[i];


int k;


for (k = i-1; k>j;k--) {


A[K+1] = a[k];


}


A[K+1] = tmp;


}


}


}





/**


* Improved insert Sort 1


* The key to the improvement is: First take the unordered table head element A[i] and ordered footer A[i-1] comparison,


* If A[I]<A[I-1], it is necessary to adjust the process:


* Start at the end of the orderly table, and move the elements larger than a[i in the ordered table to the back, until the proper position is found;


*/


public static void Insertsortadvanced (int[] a) {


Traverse unordered table;


for (int i=1; i<a.length; i++) {


If the unordered header element is less than the ordered footer, it needs to be adjusted;


if (A[i]<a[i-1]) {


int tmp = A[i];


Int J;


Search and compare from the end of an ordered table, and move the elements greater than a[i to the back to make room;


for (j=i-1; j>=0&&a[j]>tmp;j--) {


A[J+1] = A[j];


}


A[J+1] = tmp;


}


}


}





/**


* Improved Insert Sort 2


* The overall idea is similar to the above, take the unordered table header element from the orderly footer element to the forward comparison,


* If A[i] is smaller than a[i-1], move the a[i] from the end of the ordered table to the front in a bubbling exchange until it reaches the proper position;


*/


public static void InsertSortAdvanced2 (int[] a) {


Traverse unordered Table


for (int i=1; i<a.length; i++) {


Take A[i] start bubbling from the end of an orderly table;


for (int j=i-1; j>=0 && a[j] > a[j+1] j--) {//a[j+1] is a[i]


int tmp = A[J];


A[J] = a[j+1];


A[J+1] = tmp;


}


}


}

/**


* Quick Sort <br>


* The idea of the algorithm is to divide and conquer: first find an element (usually the array header element), put the larger than it to the right, put smaller than it on the left;<br>


* Then follow the idea to deal with two sub arrays; The following sub-array header element refers to the element used to divide an array;<br>


* <br>


* The following procedure key point is!forward, low0++, high0--these operations; These three operations allow A[low0],a[high0 to have a pointer to the sub array header element; <br>


* The operation of these three values can be easily understood in extreme cases: <br>


* If my sequence is 0123456789, the initial forward=false,0 as a sub array, it's clear that there will be no exchange in the first round, Low0 has been pointing 0,<br>


* High0 gradually drops until it points to 0; The same can be thought 9876543210 This example;<br>


* <br>


* @param A to be sorted array <br>


* @param subscript;<br> Starting with the low sub array


* @param subscript;<br> of the end of the high array


*/


public static void QuickSort (int[] A, int low, int high) {


if (Low>=high) {


Return


}


int low0 = low;


int high0 = high;


Boolean forward = false;


while (Low0!=high0) {


if (A[low0]>a[high0]) {


int tmp = a[low0];


A[LOW0] = A[high0];


A[high0] = tmp;


forward =!forward;


}


if (forward) {


low0++;


}


else{


high0--;


}


}


low0--;


high0++;


QuickSort (A, low, low0);


QuickSort (A, high0, high);


}





/**


* Quick sort of simple call form <br>


* Easy to test and call <br>


* @param a


*/


public static void QuickSort (int[] a) {


QuickSort (A, 0, a.length-1);


}





/**


* Merge Sort <br>


* The so-called merging, is to merge two ordered arrays; Merge sort also uses the idea of divide and conquer, dividing an array into several sub arrays;<br>


* When the length of the sub array is 1, the child array is ordered, so it is possible to merge the 22;<br>


* <br>


* Because the merging sort needs the allocation space to dump the merging result, for the convenience of the algorithm, the result of the merging algorithm appears in the form of the return value;<br>


*/





/**


* Merging two ordered arrays


* @param a ordered array 1


* @param b ordered array 2


* @return the ordered array after merging;


*/


public static int[] Merge (int[] A, int[] b) {


int result[] = new Int[a.length+b.length];


int i=0,j=0,k=0;


while (I<a.length&&j<b.length) {


if (A[i]<b[j]) {


result[k++] = A[i];


i++;


}


else{


result[k++] = B[j];


j + +;


}


}


while (I<a.length) {


result[k++] = a[i++];


}


while (J<b.length) {


result[k++] = b[j++];


}


return result;


}





/**


* Merge Sort <br>


* Divide the array from the middle, and call the left and right parts recursively until the array length is 1, starting with the 22 merge;<br>


* @param the array to be sorted;


* @return ordered array;


*/


public static int[] MergeSort (int[] a) {


if (a.length==1) {


return A;


}


int mid = A.LENGTH/2;


int[] Leftpart = new Int[mid];


int[] Rightpart = new Int[a.length-mid];


System.arraycopy (A, 0, Leftpart, 0, leftpart.length);


System.arraycopy (A, Mid, Rightpart, 0, rightpart.length);


Leftpart = MergeSort (Leftpart);


Rightpart = MergeSort (Rightpart);


Return merge (Leftpart, Rightpart);


}





/**


* Select Sort <br>


* Similar to the insertion sort, it also divides the array into ordered and unordered areas, the difference being:<br>


* Insert sort is to take the first element of the unordered area to the proper position in the ordered area, while the <br>


* Select the order from the unordered area to pick the smallest place in the ordered area last;<br>


* <br>


* Two-layer cycle, the outer control of the orderly area of the tail, the inner layer used to find the smallest element in the unordered area;<br>


* @param a


*/


public static void Selectsort (int[] a) {


for (int i=0; i<a.length; i++) {


int minindex = i;


for (int j=i+1; j<a.length; j) {


if (A[j]<a[minindex]) {


Minindex = j;


}


}


int tmp = A[i];


A[i] = A[minindex];


a[minindex]= tmp;


}


}





/**


* Hill Sort <br>


* The idea is to divide the array by equal step length (/spacing) into multiple subsequence, and to do the normal insertion sort,<br> of each subsequence to reduce the step size until the 1 is done at the end of a normal insertion sequence;


* With an extreme example, I have the following sequence of:<br>


* [1,2,3,4,5,6,7,8,9,10];<br>


* At the initial time, the step gap=5 is divided into [1,6], [2,7], [3,8], [4,9], and [5,10];<br> sorts them separately (of course because this array is special, so the result is invariant);<br>


* then GAP=2=5/2; The sub array is [1,3,5,7,9], [2,4,6,8,10]; <br>


* Final GAP=1=2/2; Do a global sort;<br>


* <br>


* Hill sort overcomes the weakness of the insert/bubble sort (the element can only move one adjacent position at a time), <br> relies on a long stride to move the element to the target position (or nearby) as soon as possible.;<br>


* Hill sort is actually a variant of the insertion sort. It applies to: when the array is in the overall order, individual needs to adjust the situation; At this time, the efficiency of O (n) can be achieved by using the advantage of insertion sort;<br>


* An important factor affecting the hill algorithm is the step selection, the advantage of a good step length: The following short step order does not break the previous long step order;<br>


* How do you understand this destruction? The previous long step moves a smaller number to the left, but it is possible to switch to the right after narrowing the step (because it is divided into a group that has a lot smaller than it);<br>


* About the step, you can view the http://zh.wikipedia.org above about Hill sort of page;<br>


* The following procedure is the most basic of hill sort, suitable for understanding Hill sort thought;<br>


*/


public static void Shellsort (int[] a) {


Control spacing, spacing gradually reduced until 1;


for (int gap = A.LENGTH/2 gap>0; gap/=2) {


Scan each sub array


for (int i=0; i<gap; i++) {


For each word group, scan the unordered area;


A[i] is the initial ordered region;


for (int j=i+gap; j<a.length; j+=gap) {


The unordered area first element is less than the ordered area tail element, indicating that you need to adjust


if (A[j]<a[j-gap]) {


int tmp = A[J];


int k = J-gap;


Search the proper position from the end of the ordered region;


while (k>=0&&a[k]>tmp) {


A[K+GAP] = a[k];


K-=gap;


}


A[K+GAP] = tmp;


}


}


}


}


}





/**


* Improved Hill sort <br>


* The improvement lies in: The above wording uses a for loop to differentiate each word group; it's actually unnecessary;<br>.


* a[0,1,... Gap-1] as an ordered region of all child arrays, A[gap,... n-1] as the unordered area of all word groups;<br>


* <br>


* This improvement is not improved in time efficiency; just make the program look more concise;<br>


* @param a


*/


public static void Shellsortadvanced (int[] a) {


Control Step Size


for (int gap = A.LENGTH/2 gap>0; gap/=2) {


Start processing from the unordered area and put multiple sub arrays together;


for (int j=gap; j<a.length; j) {


The following logic is the same as above;


if (A[j]<a[j-gap]) {


int tmp = A[J];


int k = J-gap;


while (k>=0&&a[k]>tmp) {


A[K+GAP] = a[k];


K-=gap;


}


A[K+GAP] = tmp;


}


}


}


}





/**


* Improved Hill sort 2<br>


* On the basis of absorbing the shellsortadvanced thought, the INSERTADVANCED2 approach;<br> that the first element of the disorder is moved in the form of a forward bubbling;<br>


* @param a


*/


public static void ShellSortAdvanced2 (int[] a) {


for (int gap = A.LENGTH/2 gap>0; gap/=2) {


for (int i=gap; i<a.length; i++) {


if (A[i]<a[i-gap]) {


for (int j=i-gap; j>=0&&a[j+gap]>a[j]; j-=gap) {


int tmp = A[J];


A[J] = A[j+gap];


A[J+GAP] = tmp;


}


}


}


}


}





/**


* Heap Sort <br>


* Heap Definition: The heap is a complete, or approximately complete two-fork tree, the value of the top element of the heap is greater than the value of the left and right children, the children also need to meet this condition;<br>


* According to the definition of the heap, the heap can be a large top heap (maxheap), or a small top heap (minheap);<br>


* Generally use an array to simulate the binary tree, for any element I, the left child is 2*i+1, the right child is 2*i+2; the parent node is (i-1)/2;


* @param a


*/


public static void Heapsort (int[] a) {

First from the last non-leaf node upward adjustment to meet the heap structure;


for (int i= (a.length-2)/2; i>=0; i--) {


Maxheapadjust (A, I, a.length);


}


Take the last node and the first exchange each time, then adjust the heap;


for (int i=a.length-1; i>0; i--) {


int tmp = A[i]; A[i] = a[0]; A[0] = tmp;


Maxheapadjust (A, 0, i);


}


}





/**


* Adjustment Heap <br>


* The two-fork tree with I as the node is adjusted to the heap;<br>


* You can think about this process: This complete binary tree is like a pyramid, the small elements of the tower along the tree structure, downward subsidence;<br>


* The result of the adjustment is the largest element at the top of the pyramid, and then remove it from the heap (swap it to the end of the heap and then the heap shrinks a grid);<br>


* The reason for the fast heap sorting is based on the characteristics of the binary tree, a node to settle to the appropriate position, only need to Logn step, while the results of the previous adjustment (size order) will be recorded, thus speeding up the subsequent adjustment;<br>


* @param a array to be ranked


* @param i pile top


* @param len Heap length


*/


public static void Maxheapadjust (int[] A, int i, int len) {


int tmp = A[i];


J is the left child node


int j = i*2+1;


//


while (J<len) {


Choose the big from the left and right children


J+1 is the right child node


if ((j+1) <len && A[j+1]>a[j]) {


j + +;


}


Find the right place and stop looking.


if (a[j]<tmp) {


Break


}


Otherwise move the larger person up the tree;


A[i] = A[j];


I point to the larger child just now;


i = j;


J points to the New left child node;


j = 2*i + 1;


}


The node value to be adjusted is sunk to the appropriate position;


A[i] = tmp;


}





/**


* Binary Tree sorting <br>


* The binary tree is defined as the value of the nested:<br> node is greater than the value of the left leaf node, less than the value of the right leaf node; leaf nodes also meet this requirement;<br>


* The construction process of binary tree is the process of sequencing:<br>


* Construct the node first, then call the Add method to add subsequent nodes to the node's descendants node; This process is also nested;<br>


* <br>


* Sequential traversal of binary tree to obtain ordered results;<br>


* Binary tree sorting usage is special, the use situation depends on the situation;<br>


* @param a


*/


public static void Binarytreesort (int[] a) {


Construct a binary tree node inner class to implement the two-fork tree sorting algorithm;


Class binarynode{


int value;


Binarynode left;


Binarynode right;





public Binarynode (int value) {


This.value = value;


This.left = null;


This.right = null;


}





public void Add (int value) {


if (Value>this.value) {


if (this.right!=null) {


This.right.add (value);


}


else{


This.right = new Binarynode (value);


}


}


else{


if (this.left!=null) {


This.left.add (value);


}


else{


This.left = new Binarynode (value);


}


}


}


/**


* In order to traverse the binary tree, is ordered.


*/


public void Iterate () {


if (this.left!=null) {


This.left.iterate ();


}


In the test time to turn off the output, so as not to affect performance;


System.out.print (Value + ",");


if (this.right!=null) {


This.right.iterate ();


}


}


}





Binarynode root = new Binarynode (a[0]);


for (int i=1; i<a.length; i++) {


Root.add (A[i]);


}


Root.iterate ();


}


}


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.