Quick Sort
Fast sorting is a sort algorithm of divide and conquer. It divides an array into two sub-arrays, sorting the two parts independently of each other. Quick sort and Merge sort are complementary: merge sort sorts the array into two sub-arrays, merges the ordered sub-arrays to sort the entire array, and the quick sort sorts the array in the same way that when two sub-arrays are ordered, the entire array is naturally ordered. In a merge sort, a recursive call occurs before the entire array is processed, and in quick order, the recursive call occurs after the entire array is processed.
Fast sorting algorithm is the fastest general-purpose sorting algorithm, in most cases, can be directly selected to quickly sort
As shown, the first element k as the Shard element, so that the left element is not greater than k, the right element is not less than k, so if both sides are ordered, then the entire array is ordered.
This is the basic principle of fast sorting, and if you read my previous blog about merge sort, it's easy to understand that recursion is needed here.
First on the code:
}
Public void QuickSort (integer[] A,integer Low,integer high) { if(Low >= high ) return ; = partion (a,low,high); QuickSort (a,low,j); QuickSort (a,j+1, High); }
This is the code of the recursive call, we do not care about the partion function, now only need to know that this function returns the following table of the Shard element , as shown above, returns the subscript of the k element, then divides the array into two arrays:
- Array A for all elements less than k
- Array b for all elements greater than k
- Also find a shard element in a that divides a into two sub-arrays of a '
- Also find a shard element in B to divide a into two sub-array B '
- Keep handing it down until it's no longer possible to slice
- When the smallest segmented array is ordered, it is recursively sorted again, so that the entire array is ordered at the end.
It's a little messy, but it's really good to understand. The code for the Partion function is given below:
Publicinteger partion (integer[] A,integer Low,integer high) {integer I=Low ; Integer J= high + 1; while(true) { //It is best to use ++i in loops, and if you use i++, it can lead to a lot of logic errors, i++ is when the loop ends (that is, when you run into curly braces) + +, which is why you need to use high+1 before while(a[++i]<A[low])if(i = =High ) Break; while(a[--j]>A[low])if(J = =Low ) Break; if(I >=j) Break; Change (A,I,J); } change (A,LOW,J); System.out.println ("Low:" +Low ); returnJ; }
This function can be used as a description:
1. Take the first element as a shard element
2. Find the first element greater than a[low] from low to the right
3. Find the first element less than A[high] from high to the left
4, Exchange A[low] and A[high]
5, repeat 2-4,
6. Finally, we get the result as shown in the third picture.
causes the elements on the left side of the first split element to be all less than V, the element on the right is all greater than V, and returns the subscript J of v.
The complete code is as follows:
Public classQuickSortextendsSortbase {/*(non-javadoc) * @see Sort.sortbase#sort (java.lang.integer[])*/@Override Publicinteger[] Sort (integer[] a) {print ("Init", a); QuickSort (A,0,a.length-1); Print ("Result", a); returnA; } Public voidQuickSort (integer[] A,integer Low,integer high) {if(Low >=High )return; Integer J=partion (A,low,high); QuickSort (A,LOW,J); QuickSort (A,j+1, high); } Publicinteger partion (integer[] A,integer Low,integer high) {integer I=Low ; Integer J= high + 1; while(true) { //It is best to use ++i in loops, and if you use i++, it can lead to a lot of logic errors, i++ is when the loop ends (that is, when you run into curly braces) + +, which is why you need to use high+1 before while(a[++i]<A[low])if(i = =High ) Break; while(a[--j]>A[low])if(J = =Low ) Break; if(I >=j) Break; Change (A,I,J); } change (A,LOW,J); System.out.println ("Low:" +Low ); returnJ; } Public Static voidMain (string[] args) {integer[] a= {2,1,5,9,0,6,8,7,3}; (NewQuickSort ()). sort (a); } }
Average Time complexity Nlogn
Three-direction Quick sort
In practice, an array of duplicate elements is often present, for example, we may need to sort a large number of personnel data by birthdays or by gender. In these cases, the fast sorting algorithm performs well, but there is a huge room for improvement, which is the three-way fast sort.
To put it simply, the three-direction fast sort principle is: divide the array into three parts that correspond to less than, equal to,
An array element that is greater than the Shard element. An area equal to the split element is added compared to the quick sort.
The process is as follows:
From doing the right traversal of the array once, maintaining a pointer lt makes the elements in a[low...lt-1] less than V, a pointer to the GT so that the elements in A[gt+1...high] are greater than V, a pointer I so that the elements in a[lt...i-1] are equal to V,A[I...GT] The elements in are also determined, at first I and lo are equal.
Make I increment, for a[i]:
A[i] Less than V, will a[lt] and A[i] exchange, will LT and I plus a
A[i] Greater than V, the A[GT] and A[i] are exchanged, the GT will be reduced by one
A[i] equals V, I plus one
Finally make the array present in the case:
Implementation code:
Public voidQuicksort3way (integer[] A,integer Low,integer high) {if(Low >=High )return; Integer LT=Low ; Integer I= low + 1; Integer GT=High ; while(i<=GT) { if(A[i] <A[lt]) {Change (A,I,LT); I++; Lt++; } Else if(A[i] >A[lt]) {Change (A,I,GT); //It is not possible to use i--, since swapping a[gt] and A[i], now A[i] does not have a location, and if you use i++, the ordering of the element will be skipped after the interchangeGT--; } Else{i++; } Print (A, a); } quicksort3way (A,low,lt-1); Quicksort3way (A,gt+1, high); }
Operation Result:
Init: [2, 1, 5, 9, 0, 6, 8, 7, 3]a: [1, 2, 5, 9, 0, 6, 8, 7, 3]a: [1, 2, 3, 9, 0, 6, 8, 7, 5]a: [1, 2, 7, 9, 0, 6, 8, 3, 5]a: [1, 2, 8, 9, 0, 6, 7, 3, 5]a: [1, 2, 6, 9, 0, 8, 7, 3, 5]a: [1, 2, 0, 9, 6, 8, 7, 3, 5]a: [1, 0, 2, 9, 6, 8, 7, 3, 5]a: [1, 0, 2, 9, 6, 8, 7, 3, 5]a: [0, 1, 2, 9, 6, 8, 7, 3, 5]a: [0, 1, 2, 6, 9, 8, 7, 3, 5]a: [0, 1, 2, 6, 8, 9, 7, 3, 5]a: [0, 1, 2, 6, 8, 7, 9, 3, 5]a: [0, 1, 2, 6, 8, 7, 3, 9, 5]a: [0, 1, 2, 6, 8, 7, 3, 5, 9]a: [0, 1, 2, 6, 5, 7, 3, 8, 9]a: [0, 1, 2, 5, 6, 7, 3, 8, 9]a: [0, 1, 2, 5, 6, 3, 7, 8, 9]a: [0, 1, 2, 5, 3, 6, 7, 8, 9]a: [0, 1, 2, 3, 5, 6, 7, 8, 9]a: [0, 1, 2, 3, 5, 6, 7, 8, 9]result: [0, 1, 2, 3, 5, 6, 7, 8, 9]
Average time complexity: between N and Nlogn
Quick sort and three-direction quick sort