Essential for Java programmers-quick sorting of data structures and algorithms (1)

The basic idea of ​​quick sort:

Regarding the issue of quick sorting algorithm, it can also be equivalent to a typical example of implementing the divide-and-conquer algorithm. First, a series of unsorted sequences is divided into two left and right sequences S1 and S2 through a reference number. The elements of S1 are all larger than the reference number. Small, the elements of S2 are all larger than the reference number, and then quickly sort the left and right sequences again. You can find the reference numbers of S1 and S2 at will. It is not necessary to set the lowest bit as the reference number every time. In this way If the subsequences (including subsequences of S1 and S2) are subjected to the quick sort sorting algorithm, the final generated sequence will naturally become an ordered sequence.
Describe using the steps of the divide-and-conquer algorithm idea:
1. Division step: Select a benchmark number, and then divide the sequence so that part is larger than the benchmark number and part is smaller than the benchmark number.
2. Governance step: recursively sort subsequences
3. Combination step: This algorithm does not have this step

Abstract ideas cannot give us a clear understanding of the quick sort algorithm. Let us borrow a vivid explanation from a post on the 51CTO forum to give us a clear understanding of quick sort:

Suppose now we sort the 10 numbers "6 1 2 7 9 3 4 5 10 8". First, randomly find a number in this sequence as the base number. For convenience, let the first number 6 be the base number. Next, you need to place all the numbers in this sequence that are larger than the base number on the right side of 6, and the numbers that are smaller than the base number on the left side of 6, similar to the following arrangement:

3 1 2 5 4 6 9 7 10 8

In the initial state, the number 6 is at position 1 of the sequence. Our goal is to move 6 to a position somewhere in the middle of the sequence, let's say this position is k. Now we need to find this k, and take the k-th position as the dividing point. The numbers on the left are all less than or equal to 6, and the numbers on the right are all greater than or equal to 6.
Start "probing" from both ends of the initial sequence "6 1 2 7 9 3 4 5 10 8". First find a number less than 6 from right to left, then find a number greater than 6 from left to right, and then swap them. Two variables i and j can be used here to point to the leftmost and rightmost parts of the sequence respectively. We give these two variables nice names "Sentinel i" and "Sentinel j". At the beginning, let the sentinel i point to the leftmost side of the sequence (ie i=1), pointing to the number 6. Let sentinel j point to the rightmost part of the sequence (i.e. = 10), pointing to the number.

Write picture description here

First, Sentinel J began to dispatch. Because the reference number set here is the leftmost number, it is very important to send sentinel j first (please think about why). Sentinel j moves to the left step by step (i.e. j–) until it finds a number less than 6 and stops. Next, sentinel i moves to the right step by step (ie i++) until it finds a number greater than 6 and stops. Finally, sentry j stopped in front of the number 5, and sentry i stopped in front of the number 7.

Write picture description here

Now swap the values ​​of the elements pointed to by sentinel i and sentinel j. The sequence after the exchange is as follows:

6 1 2 5 9 3 4 7 10 8
Write picture description here

At this point, the first exchange ends. Next, sentry j continues to move to the left (a friendly reminder, sentry j must start first every time). He stopped after finding 4 (which was smaller than the base number 6, meeting the requirements). Sentinel i also continued to move to the right. He found 9 (which was larger than the base number 6, meeting the requirements) and stopped. At this time, the exchange is performed again, and the sequence after the exchange is as follows:

6 1 2 5 4 3 9 7 10 8

The second exchange is over and "probing" continues. Sentinel j continued to move to the left. He found 3 (smaller than the base number 6, meeting the requirements) and then stopped. Sentinel i continues to move to the right, oh no! At this time, sentry i and sentry j met, and both sentry i and sentry j came to 3. Indicates that "detection" ends at this time. We swap the base numbers 6 and 3. The sequence after the exchange is as follows:

3 1 2 5 4 6 9 7 10 8
Write picture description here

At this point the first round of "detection" is truly over. At this time, the base number 6 is used as the dividing point. The numbers to the left of 6 are all less than or equal to 6, and the numbers to the right of 6 are all greater than or equal to 6. Looking back at the process just now, in fact, the mission of sentry j is to find a number smaller than the benchmark number, and the mission of sentry i is to find a number greater than the benchmark number until i and j meet.
OK, explanation completed. Now that the base number 6 has been returned, it happens to be at position 6 in the sequence. At this point we have split the original sequence into two sequences with 6 as the dividing point. The sequence on the left is "3 1 2 5 4" and the sequence on the right is "9 7 10 8". Next, you need to process these two sequences separately. Because the sequences on the left and right of 6 are still very confusing. But it doesn’t matter, we have mastered the method. Next, we only need to simulate the method just now to process the sequences on the left and right of 6 respectively. Now let’s deal with the sequence on the left side of 6 first.
The sequence on the left is "3 1 2 5 4". Please adjust this sequence with 3 as the base number, so that the numbers to the left of 3 are all less than or equal to 3, and the numbers to the right of 3 are all greater than or equal to 3. Okay, let’s start writing.
If your simulation is correct, the order of the sequence after adjustment should be:

2 1 3 5 4

OK, now 3 is back in place. Next, we need to process the sequence "2 1" on the left of 3 and the sequence "5 4" on the right. The sequence "2 1" is adjusted based on 2. After processing, the sequence is "1 2", and 2 has returned to its original position. The sequence "1" has only one number and does not require any processing. At this point, we have completely processed the sequence "2 1" and obtained the sequence "1 2". The sequence "5 4" is also processed in this way, and the final sequence obtained is as follows:

1 2 3 4 5 6 9 7 10 8

For the sequence "9 7 10 8", the same process is simulated until no new subsequence can be split. Eventually you will get a sequence like this, as follows

1 2 3 4 5 6 7 8 9 10

At this point, the sorting is completely completed. Careful students may have discovered that each round of quick sorting is actually to return the benchmark numbers of this round. Until all the numbers are returned, the sorting is over. The following domineering picture describes the processing process of the entire algorithm.

Write picture description here

Guess you like

Origin blog.csdn.net/NTSDB/article/details/52730753