Quick sorting (with Java implementation and analysis)

Source: Internet
Author: User

Quick sorting (with Java implementation and analysis)

To sum up the quick sorting, if any errors or deficiencies exist, please share with us.

1. Fast sorting

The idea of fast sorting is similar to that of Merge Sorting. Quick sorting by selecting an element, called a pivot element or sharding element, puts it in a proper position so that the element before it is no greater than it, the element after it is not smaller than it, and then the pivot element is the demarcation point, the arrays on both sides also adopt a similar method, that is, the pivot element is selected, so that the previous element is not greater than it, repeat the following element until there is only one element in the array (recursive exit condition ).

2. partition Function

From the above description, quick sorting requires recursion, recursively selecting pivot elements for segmentation. ThereforeImplementation focusIs the partition function, that is, how to implement all the partition elements, so that the elements before it are not greater than it, followed by not less than it.

3.1 Implementation of the partition Function

Idea in Algorithm Fourth Edition: For a pivot element, scan from the first element to find the first element greater than it, and then scan forward from the last element, find the first element smaller than it and exchange two elements. Note that the array access is not out of bounds during scanning, and the scanning start position cannot overlap.

Package c2Sorting; /*** Implementation of the first partition for fast sorting * @ author * @ date April 2, 2016 10:03:53 * http://blog.csdn.net/xiaoguobaf */public class QuickSort_1 {public static void sort (int []) {// driver sort (a, 0,. length-1);} private static void sort (int [] a, int lo, int hi) {if (lo> = hi) // recursive exit judgment condition return; int p = partition (a, lo, hi); // For an element, it does not have to be involved in recursion, because its location must be equal to or greater than the preceding one, the following values are not less than sort (a, lo, P-1); sort (a, p + 1, hi);} private static int partition (int [] a, int lo, int hi) {int left = lo; // left pointer for scanning. int right = hi + 1; // right pointer for scanning, 1 is added to facilitate scanning. int cursor = a [lo]; while (true) {while (a [+ + left] <= cursor) // starts from lo, find the element greater than the limit and use ++ before accessing the array to make it safer. Then ++ may cross-border if (left = hi) // prevents cross-border break; while (a [-- right]> = strong) // starting from hi, find the element if (right = lo) that is less than strong. // prevent cross-border break; if (left> = right) // The left and right scans intersect with each other. When the iteration ends, the condition is determined. when the conditions are equal, it indicates that the break element is equal to the limit; swap (a, left, right ); // exchange the elements before the sequence greater than the sequence and those after the sequence smaller than the sequence, // from here we can see that the fast sorting is unstable, because the two have elements equal to left or right, the original order is damaged} swap (a, lo, right ); // place the pivot element in a proper position. // before the pivot element is not handed over to a proper position, all the elements in other positions meet the scanning conditions (the two while elements are true ), then perform another scan. The scan conditions are false. right <= left, and the element where right is located is the return right that is not greater than limit; // return the location of the split element} private static void swap (int [] a, int I, int j) {// when no duplicate elements exist in the array to be sorted, you can use an exclusive or operation. However, if there are duplicates, the duplicate elements will be set to 0 int temp = a [I]; a [I] = a [j]; a [j] = temp;} // unit test public static void main (String [] args) {int [] a = {,}; sort (a); for (int I = 0; I <. length; I ++) System. out. print ("" + a [I] + "") ;}/ *** output: 1 1 2 3 3 4 5 6 7 8 9 **/
3.2 partition function implementation 2

Select the first element as the pivot element and use index as the pointer of the currently scanned element. storIndex indicates the last pointer behind the pivot element that is less than the pivot element, scans from left to right starting from the first element behind the pivot element. If the element currently being scanned is smaller than the pivot element, then, after scanning the elements of the index and the ++ storIndex (that is, the first element not smaller than the pivot element), the pivot element is exchanged with the storIndex element, to place the pivot element in a proper position.
Click here and select QUICK to view the dynamic execution.

Package c2Sorting; /*** implementation of the second partition for fast sorting * @ author * @ date April 2, 2016 4:24:47 * http://blog.csdn.net/xiaoguobaf */public class QuickSort_2 {public static void sort (int []) {sort (a, 0,. length-1);} private static void sort (int [] a, int lo, int hi) {if (lo> = hi) return; int p = partition (, lo, hi); sort (a, lo, P-1); sort (a, p + 1, hi);} private static int partition (int [] a, int lo, int hi) {// when I implement this partition function, I feel that ++ is not safe to use when accessing the array. Otherwise, stack overflow and NULL pointer exceptions may occur. int index = lo; // pointer int storIndex = lo for the currently scanned element; // The Last pointer while (++ index <= hi) smaller than the pivot element) if (a [index] <a [lo]) swap (a, index, ++ storIndex ); // swap the current element with the first element swap (a, lo, storIndex) not less than the pivot element; // place the pivot element in the appropriate position return storIndex; // return the position of the pivot element, that is, the index} private static void swap (int [] a, int I, int j) {int temp = a [I]; a [I] = a [j]; a [j] = temp;} // unit test public static void main (String [] args) {int [] a = {,}; sort (a); for (int I = 0; I <. length; I ++) System. out. print ("" + a [I] + "") ;}/ ** output: 1 1 2 3 3 4 5 6 7 8 9 */
3.3 partition Function Implementation 3

First, save the pivot element temporarily, scan from right to left, find the first element smaller than the pivot element, place it to the position of the pivot element, and then scan from left to right, locate the first element greater than the pivot element and place it in the first position earlier than the pivot element.

Package c2Sorting; /*** fast sorting of the third partition implementation * @ author pot * @ date April 2, 2016 11:39:05 * http://blog.csdn.net/xiaoguobaf */public class QuickSort_3 {public static void sort (int []) {sort (a, 0,. length-1);} private static void sort (int [] a, int lo, int hi) {if (lo> = hi) return; int p = partition (, lo, hi); sort (a, lo, P-1); sort (a, p + 1, hi);} private static int partition (int [] a, int lo, int hi) {int lower = a [lo]; while (lo 

Compared with the three implementations, the second is the worst. Compared with the first implementation method, the second is at least twice the number of exchanges in the same sort; compared with the first and third implementation methods, the third method accesses the array less frequently, because the first method adopts exchange, and the first method is easy to implement, the third type of code is more compact, so it is a little difficult to understand.

4. Improved quick sorting 4.1 improved selection of pivot Elements

In the best case, the pivot element should be the average value of all elements, that is, the value, so that it is closer to the splitting of Merge Sorting. However, the preceding three partition implementations are the pivot elements selected as the first element. This guarantee is not ensured. The three-digit median method (three sampling splitting) is used to compare lo, mid, hi, select one of the middle as the pivot element.

// Triplicate split private static int threeMedium (int [] a, int lo, int mid, int hi) {return (a [lo]

In fact, it can also be divided by 5 samples, which will be closer to the middle number, but it is too cumbersome.

4.2 switch to insert sorting

For small-scale arrays, insertion sorting is enough. The number of times that an array can be split multiple times by fast sorting is more than that of insert sorting. Therefore, the array size is small, switch to insert sorting.

The improved quick sorting Java Implementation is attached.

Package c2Sorting;/*** improved quick sorting * @ author small pot ba * @ date April 6, 2016 10:38:53 * http://blog.csdn.net/xiaoguobaf */public class QuickSort {private static final int CUTOFF = 10; // If the array size does not exceed CUTOFF, switch to the insert sort public static void sort (int [] a) {sort (a, 0,. length-1);} private static void sort (int [] a, int lo, int hi) {if (lo + CUTOFF> = hi) {// switch to insert sort, call insert sort and return insertionSort (a); return ;}if (lo >= hi) return; // exchange the number of three samples with lo int m = threeMedium (, lo, lo + (hi-lo)/2, hi); swap (a, m, lo); int p = partiton (a, lo, hi); sort (, lo, P-1); sort (a, p + 1, hi);} private static int partiton (int [] a, int lo, int hi) {int lower = a [lo]; while (lo 
5. Quick Sort Analysis 5.1 time complexity

Both quick sorting and Merge Sorting use recursion, so we can use Recursive Formulas for analysis. For a fast sorting that does not adopt insertion sorting conversion and three sampling splitting, the running time is equal to the sorting time of the two subseries plus the time spent on splitting, because of scanning, obviously, the time spent in splitting is positively related to the array size. Therefore, the following formula is obtained:
T (N) = T (I) + T (N-i-1) + cN
N is the size of the array, I is the number of elements in a smaller part after splitting, and c is a constant.

(1) Worst Case
The pivot element is always the smallest element. At this time, I is always 0, T (0) = T (1) = 1, and it is irrelevant to the problem scale. You can ignore it in a push formula, so we get: T (N) = T (N-1) + cN, repeatedly use this formula until N is 2, and then accumulate.

(2) Best case
In the best case, the pivot element is a number. to simplify the analysis, assuming that the size of both sub-arrays is half of the original array, the analysis and Merge Sorting are similar.

(3) Average
<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxoMyBpZD0 = "52-spatial complexity"> 5.2 space complexity

In the best case and average case, the number of sort recursion times is log2N, and the space occupied by the local variable at the position of the pivot element returned by partition is log2N, the local variables in the partition function are also proportional to log2N, that is, the space complexity is O (log2N). In the worst case, the number of sort recursion times is N ^ 2, at this time, the space complexity will be O (N ^ 2), but this probability is very small, and it will be reduced after three sampling. If the array is disrupted before sorting, the probability of this situation is negligible. For proof, see Algorithms Fourth Edition.
Therefore, the space complexity of quick sorting is O (log2N)

5.3 Stability

There are two aspects of instability. The first one has been mentioned in the first implementation. The second is to place the pivot element in the correct position before the partition function returns, if the elements whose values are equal to those of the pivot element before the position to be placed are not stable.

For more information about the number of comparisons, exchanges, and total number of visits to the array, see Algorithms Fourth Edition to analyze the time complexity and space complexity.

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.