Ten thousand words sorting: introduction to algorithm 0 foundation - a large collection of mainstream sorting algorithms; Hard core sorting diagram + code -- Summary of data structure and algorithm 4

Current brain map:

1. Preface: on algorithm color change? Duck, no!

     I wonder if you have this feeling? When it comes to algorithms, the first reaction is: it's too difficult, I won't! I had this feeling at the beginning, but after learning patiently, I found that the algorithm was not so complex. At least getting started is an easy thing, just:

    1. Read this tweet patiently!

    2. Start thinking about the implementation of any algorithm!

    3. Try to write any implementation code yourself!

As long as you successfully write one, you will get started, and you can do it! As for the depth of the later stage, it depends on how long you have spent~

2. Do you have to master the algorithm?

     I think: it depends on my own requirements. If the requirement for myself is to be an ordinary developer, it's not a big problem not to learn algorithms. It is enough to meet the simple needs of CRUD daily (generally, 2W monthly salary is the ceiling).

     However, if you want to become a senior development engineer or want to enter a large factory with an annual salary of more than 50W, the algorithm is a necessary threshold. In the interview of a large factory, many people can be stuck in the algorithm section alone ~ so whether the algorithm is important or not mainly depends on your own requirements!

             The following figure shows one of the two algorithm problems encountered by a large factory in an interview:

3. Getting started: sorting algorithm

     There are many algorithms. This entry focuses on sorting algorithms; There are many scenes in life that need to be sorted. For example, if you often visit Taobao, someone needs to sort according to the price from low to high; Another example is the microblog hot search ranking we often see. In fact, it is also a sort according to the number of user clicks. It can be said that life is sorted everywhere. How do the bottom do so? Sorting algorithm starts~

     Sorting algorithms can be divided into different categories according to different standards. However, it is not helpful to know these classification names for getting started, so we can eliminate those complex ones and directly divide them into two categories according to the degree of difficulty:

     I. simple sorting: 1. Bubble sorting     2. Select Sorting     3. Insert sorting (suitable for getting started)

     two   Complex sorting: 1. Hill sorting     2. Merge and sort     3. Quick sort (suitable for advanced)

     three point one      Bubble sorting

         Suggestion: three steps for algorithm learning: (four steps occasionally)

     Step 1: what is bubble sorting?

         Bubble Sort: repeatedly access the element column to be sorted, compare two adjacent elements in turn, and exchange them if the order meets the requirements (such as from large to small). This process is repeated until no adjacent elements need to be exchanged, that is, the element column has been sorted.

The name of this algorithm comes from the fact that the larger elements will slowly "float" to the top of the sequence (in ascending or descending order) through exchange, just as bubbles in the water will eventually float to the top, so it is called "bubble sorting". Example above:

A number of team leaders:

Integer[] arr = {85, 7, 9, 56, 47, 1, 2, 8, 5};

If you look up, it becomes like this:

Therefore, what we need to do now is to "float" the elements with large values in the array to the top, just like spitting bubbles. The bubbles on the top are larger (the values are larger); (drawings are only provided for easier understanding)

     Step 2: bubble sorting algorithm diagram

     Requirement: a string of arrays: 3 5 9 7 2 1. The result after sorting is required to be from small to large: 1 2 3 5 7 9.

Let's take a look at the overall process of bubble sorting. I have an overall impression:

     The first round of bubble decomposition steps (each round of process is similar):

1. Element 3 is compared with adjacent element 5, 3 < 5, and the position is not exchanged;

2. Compare the size of element 5 and element 9: 5 < 9, do not exchange positions;

3. Compare the size of element 9 and element 7: 9 > 7, exchange position;

4. Compare the size of element 9 and element 2 in the new position: 9 > 2, exchange the position;

5. Compare the size of element 9 and element 1 in the new position: 9 > 1, exchange the position, there is no element on the right, and the first round ends;

6. Array status after the first round of bubbling: find the corresponding position of the largest element;

The second round of bubble sorting: put the second largest element in the corresponding position;

The third round of bubble sorting: put the third largest element in the corresponding position;

The fourth round of bubble sorting: put the fourth largest element in the corresponding position;

The fifth round of bubble sorting: put the fifth largest element in the corresponding position;

In other words, if there are N elements, there will be N-1 rounds of sorting; Each round of exchange process is similar and will not be repeated here;

     The third step is to realize bubble sorting by handwritten code

     API to be implemented: (it is recommended to code first. The process is more important than the result)

1.sort(Comparable[] a): traverse, call greater and exchange methods to complete sorting;

2.greater(Comparable c1, Comparable c2): compare the sizes of two adjacent elements;

3.exchange(Comparable[] a, int b, int c)  : Exchange the position of two elements;

greater() is required for subsequent sorting algorithms; exchange(); It will not be listed later;

public class MyBubble {    //Sort public static void sort(Comparable[] a) {/ / there are length-1 elements to be exchanged. For (int i = 0; I < a.length - 1; I + +) {/ / the elements at index 0 should be exchanged. In the worst case, it should be exchanged until length-1 times. For (int j = 0; J < a.length - 1 - I; j + +) {/ / if a[j] is greater than a[j+1] If it is large, the exchange location is if (greater (a[j], a[j+1]) {exchange (a, J, j + 1);}}}} / / compare the size public static Boolean greater (comparable C1, comparable C2) {/ * / / return C1. CompareTo (C2) > 0; disassembled version: int compare = c1.compareto (C2) ; return compare > 0; * / return C1. CompareTo (C2) > 0;} / / public static void exchange(Comparable[] a, int b, int c) {/ / create a temporary element for exchange and transit. / / the elements after the equal sign of the first function are the elements before the equal sign of the next function, which are connected from beginning to end, that is, complete the exchange. Comparable num = a [b]; a [b] = a [C]; a [C] = num;}}

         Add: energetic people can think about the time complexity of bubble sorting?

Tip: suppose the worst case of bubble sort: how many times does a completely inverted array containing N elements need to be exchanged to complete the sort?

         Derivation process (process is more important than result!)

     Number of times the first element needs to be exchanged: N-1

     Number of times the second element needs to be exchanged: N-2

     Number of times the third element needs to be exchanged: N-3

    ......

     Number of times the nth-1st element needs to be exchanged: 1

     The nth element does not need to be exchanged and is in positive order at this time;

     Finally, the total number of exchanges required: 1+2+3+...+N-1=   (N*(N-1))/2=N^2/2 - N/2;

     According to the de clutter rules of time complexity, the final time complexity is simplified as:

    F(N)= O(N^2);

     three point two     Select sort

     First step      What is selective sorting?

     The working principle of Selection sort is to select the smallest (or largest) element from the data elements to be sorted for the first time, store it at the beginning of the sequence, and then find the smallest (large) element from the remaining unordered elements, and then put it at the end of the sorted sequence. And so on until the number of all data elements to be sorted is zero. (if you don't understand, skip to the step for detailed explanation)

     Step 2: Select Sorting Algorithm diagram

     Requirements: a string of arrays: 9 18 38 2 46 8 43 46 5 12. The results are required to be sorted from small to large

Let's take a look at the overall process of selection and sorting. We have an overall impression:

Green is the traversal process;

Red is the index position mark of the current minimum element;

Orange is the ordered element and does not participate in the next round of sorting;

    

     The first round of sorting and decomposition steps (the process of each round is similar):

    1. Compare element 9 with adjacent element 18, 9 < 18, red mark Record 9, index position 0;

     2. Comparison between element 9 and element 38, 9 < 38, red mark Record 9, index position 0;

    3. Comparison between element 9 and element 2, 2 < 9, red mark record 2, index position 3;

    4. Comparison between element 2 and element 46, 2 < 46, red mark record 2, index position 3;

    5. Comparison between element 2 and element 8, 2 < 8, red mark record 2, index position 3;

(the subsequent comparison process is consistent, so some figures are omitted)

    6. Comparison between element 2 and element 43, 2 < 43, red mark record 2, index position 3;

    7. Comparison between element 2 and element 46, 2 < 46, red mark record 2, index position 3;

    8. Comparison between element 2 and element 5, 2 < 5, red mark record 2, index position 3;

    9. Comparison between element 2 and element 12, 2 < 12, red mark record 2, index position 3;

    10. Red mark the minimum element index of the final record as 3, exchange the elements of index 0 and index 3, and the first round ends;

The second round of sorting: put the second smallest element at the 1 index position;

The third round of sorting: put the third smallest element at the 2 index position;

The fourth round of sorting: put the fourth smallest element at the 3 index position;

The fifth round of sorting: put the fifth smallest element at the 4 index position;

. . . . . .

In other words, if there are N elements, there will be N-1 rounds of sorting; Each round of exchange process is similar and will not be repeated here;

     The third step is to select and sort by handwritten code

(there is the basis of bubble sorting in front, which is not difficult to implement. Try your own code)

     API to be implemented:

  1. sort(Comparable[] a): traverse, call greater and exchange methods to complete sorting;

    The following two API s have been implemented previously, and ready-made ones can be used (and subsequent algorithm implementations will not be shown)

    2.greater(Comparable c1, Comparable c2);

    3.exchange(Comparable[] a, int b, int c) ;

/** * 2.Select Sorting * idea: in each round, first assume that the first element is the smallest, and then compare each subsequent * with the first element in turn. After comparison, determine the minimum value and update the minimum value *! last! Re interchange element * code idea (double cycle): */public static void selectSort(Comparable[] arr) {    //1. Outer loop condition: a total of arr.length - 1 for (int i = 0; I < arr.length - 1; I + +) {/ / 2. indexMin is used to store the minimum element index of each round. Int indexMin = I; / / 3. Inner loop condition in the I round: use the elements at indexMin to compare them with each other in the back to determine the minimum element index for (int j = I + 1; J < arr.length; j + +) {if (greater (arr [indexMin], arr [J]))) {/ / record the minimum element subscript indexMin = j;}} / / exchange the element exchange(arr, i, indexMin);}}

     Add: what is the time complexity of sorting?

     Time complexity analysis of selective sorting: a double-layer for loop is used for selective sorting, in which the outer loop completes data exchange and the inner loop completes data comparison:

Data comparison times: (N-1)+(N-2)+(N-3)+...+3+2+1 = N^2/2 - N/2

Data exchange times: N-1 times

Time complexity F (n) = N^2/2 - N/2 +N-1 =N^2/2 + N/2 - 1=O(N^2)

three point three     Insert sort

     First step      What is insert sort?

     The basic idea of insertion sort is to insert a record into the ordered table that has been arranged, so as to create a new ordered table with the number of records increased by 1. In its implementation process, a double-layer loop is used. The outer loop searches for all elements except the first element, and the inner loop moves the ordered table in front of the current element, for example Is to play poker, players get a messy set of cards and start sorting. The way is: take out the smallest card of all the remaining cards each time and put it in the front position;

Then take out a slightly larger card and put it in the second position, and so on. This is an insertion sort; (if you don't understand, jump to the step for detailed explanation)

     Step 2: insert sorting algorithm diagram

     Requirements: a string of arrays: 5 6 3 1 8 7 2 4. The results are required to be sorted from small to large

Old rules, look at the picture:

Green is the element displaced backward;

Red is the element to be inserted under operation;

Orange is the temporarily ordered element;

     First round sorting decomposition steps (starting from index 1):

    1. Element 6 at index 1 is compared with element 5 of index 0, 5 < 6, stand still;

    2. Element 3 at index 2 is compared with the previous element 6. If 3 < 6, change the position;

Element 3 is compared with element 5 of index 0, 3 < 5, change position

There are no elements to compare, insert;

3. Compare element 1 at index 3 with previous element 6, 1 < 6, change position;

     three point one      Element 1 is compared with the previous element 5, 1 < 5, change the position;

     three point two    Element 1 is compared with element 3 earlier, 1 < 3, change position;

     three point three    Element 1 has no element to compare and the insertion position;

After completing the above process:

4. Element 8 at index 4 is compared with the previous element 6. If 6 < 8, find an element smaller than yourself and hold still;

5. Element 7 at index 5 is compared with the previous element 8. If 7 < 8, change the position;

    five point one     Element 7 is compared with element 6 earlier. If 6 < 7, you find an element smaller than yourself and don't move;

After completing the above process:

6. Compare element 2 at index 6 with the previous elements, and the subsequent operations are the same;

7. Comparing element 4 at index 7 with the previous elements, the subsequent operations are the same;

The final results are as follows:

The third step is to insert and sort the handwritten code

(try your own code!!!)

     API to be implemented:

  1. sort(Comparable[] a): traverse, call greater and exchange methods to complete sorting+ greater(...)+exchange(...)  ;

/** * 3.Insert sorting * idea: insert * from the element at the second position in the array, compare with the previous elements in turn, and execute the same operation to the last position of the array * code idea (double loop): */public static void insertingSort(Comparable[] arr) {    //1. External circulation condition: a total of arr.length - 1 time is required for position exchange operation / / the condition can be written as I < arr.length; It can also be written as I < = arr.length - 1 for (int i = 1; I < arr.length; I + +) {for (int j = I; J > 0; J --) {if (greater (arr [J - 1], arr [J]))) {exchange (arr, J - 1, J);}}}}}

​​​​​​​

Add: what is the time complexity of insertion sorting?    tips: Calculate considering the worst case, i.e  <8 7 6 5 4 3 2 1>;    The reasoning method is similar to the previous one:    Time complexity F(N)= O(N^2);

(congratulations! If you insist on seeing here and implement the code, you have successfully entered the door of the algorithm with one foot!)

     Have you found that the time complexity of simple sorting is O(N^2). With the increase of the amount of data, the amount of time consumed is also very large. Is there a sorting algorithm with lower time complexity: the time complexity is low, but it can also achieve the effect?

     Yes, that's the next complex sort!

     In the insertion sort above, if the sequence to be sorted is just in reverse order, such as

Sequence 1: {9,8,7,6,5,4,3,2,1}

and

Sequence 2: {2,4,6,8,1,3,5,7,9}

The comparison result of the number of operations required for insertion sorting is obvious: sequence 1 > sequence 2

The sorting optimization direction is to make the sequence to be operated more orderly, which can reduce the number of operations and reduce the time complexity. What should we do? Hill sort is one of the ways to "optimize" the sequence of numbers;

     three point four     Shell Sort

     First step      What is Hill sort? (it is recommended to directly look at the step-by-step diagram)

    Shell's sort is a kind of insertion sort, also known as "narrowing increment sort", which is a more efficient improved version of direct insertion sort algorithm.

     Hill sort is to group records by certain increment of subscript, and sort each group by direct insertion sort algorithm; As the increment decreases, each group contains more and more keywords. When the increment decreases to 1, the whole file is just divided into one group, and the algorithm terminates. (from Du Niang, I can't understand   It is strongly recommended to look at the diagram. Understanding the process is almost equivalent to understanding the definition)

     Step 2: Hill sorting algorithm diagram

     The core of Hill sort is to define a gradient gap, divide the sequence into different groups according to h, insert sort in different groups first, and then insert sort with gap=1, that is, the whole sequence; Because the previous operations have made the sequence relatively more orderly, the number of exchanges required for the last insertion sorting is greatly reduced;

     Requirements, a string of arrays: 8 9 1 7 2 3 5 4 6 0, the results are required to be sorted from small to large;

Dynamic diagram:

Decomposition steps of the first round of hill sorting:

1. In the first round of grouping insertion sorting, first determine that the gradient gap is 10 / 2 = 5, then the grouping is as follows:

Group 18 at index 03 at index 0 + 5
2 groups9 at index 15 at index 1 + 5
3 groups1 at index 24 at index 2 + 5
4 groups7 at index 36 at index 3 + 5
5 groups2 at index 40 at index 4 + 5

2. Group, insert and sort the same group in turn;

    2.1 insert and sort 8 at index 0 and 3 at index 0 + 5 first;

     After sorting:

    2.2 insert and sort 9 at index 1 and 5 at index 1 + 5;

    2.3 insert and sort 1 at index 2 and 4 at index 2 + 5;

    . . . The subsequent operations are the same until the sorting operation of the last small group is completed;

After the first round, the sequence becomes more relatively orderly:

The second round of grouping insertion sorting:

    1. If the gradient gap is determined to be gap/2=2 (the remainder is removed), the new grouping is as follows:

first group{3,1,0,9,7} at index 0, 2, 4, 6, 8
Group 2{5,6,8,4,2} at index 1, 3, 5, 7, 9

    2. Insert and sort the two small groups in turn;

     (because the step-by-step diagram is clear before inserting and sorting, there is no waste of pen and ink here)

The third round of grouping sorting:

     1. Determine the gradient gap as gap/2=1 (the remainder is removed), then the new grouping is the whole sequence, and the rest is the same as the insertion sorting, so directly po the final result

Let's make a brief summary: the key to understanding Hill ranking is the understanding of each grouping gradient;

  Step 3 handwritten code to realize Hill sorting

PS: the difficulty has been upgraded. I spent a long time figuring this out. Finally, I found two key points in understanding:

1. Understanding of gradient h (the h character I use represents gradient)     

2. When the code implementation finds the elements to be inserted, it can be from the front to the back (traversing from index 1 in turn like the implementation of insertion sorting), or from the back to the front (from the last index in turn);

For me, I find it easier to understand from the back to the front!

The code is as follows:

//Hill sorting idea: each round groups the arrays according to different gradients, and each small group is sorted by insertion; public static void shellSort(Comparable[] arr) {/ / initialize the gradient h int h = 1; while (H < arr.length / 2) {H = 2 * H + 1;} / / group by gradient while (H > = 1) {/ / 1. Find the element to be inserted for (int i = h; I < arr.length; I + +) {/ / the second for loop must be well understood; / / int j = i: it means to find the elements that need to be moved and inserted into the ordered array every time / / J > = H: it means the critical value is > = h, so as to ensure that the following j-h will not exceed / / j -= h: the insertion sorting in the group is from the back to the front / / 2. Insert the elements to be inserted For (int j = i; J > = h; j -= h) {/ / the element to be inserted is arr[j], compare arr[j] and arr[j - H] if (greater (arr[j - H], arr[j])) {exchange (arr, J - H, J);} else {/ / the element to be inserted has found the appropriate position, and the loop break ends;}}} / / the gradient is halved h /= 2;}}

     Hill sort has a special time complexity, which is slightly better than O(n^2), but its performance is not as good as O(nlogn). The key is to master the derivation process of time complexity of bubble sort and merge sort at least;

three point five     Merge sort

     First step      What is merge sort;

     First of all, I'll give you po a picture. You must be very interested! Yes, it's the promotion map of professional E-sports competition. For example, many teams want to compete for the championship. How to evaluate? It's the way of decentralized promotion. First select the top eight, then the top four, and finally determine the champion in the final of the top two;

     What if the current demand is not to select the strongest, but to form a row from left to right according to combat effectiveness? That becomes the merging sort to be talked about now!!! This process of separating, comparing and then merging is called merging;

     Step 2: merge sorting algorithm diagram

Requirement: a string array: {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

The results shall be sorted from small to large;

Hey ~ this time, first look at the decomposition diagram, and then look at the motion diagram (because I found that I couldn't understand the animation before, I didn't understand it until decomposition, so the learning methods should be flexible and diverse, and I can't go to the black in the same way!)

     For convenience, I took eight elements for demonstration. The decomposition diagram is as follows:

separate:

Merge: (the red arrow points to sorting and exchange operations, which is different from the above figure)

Next, you can understand the dynamic diagram:

PS: the same color is the same small group;

Step 3: merge and sort by handwritten code (first, you need to understand the concept and use of recursion):

     API to be implemented:

Member method:

1.public static void mergeSort(Comparable[]arr):Pair array arr Sort the elements within; 2.private static void mergeSort(Comparable[]arr,int low,int high):Pair array arr Index in low To index high Sort the elements between; 3.private static void merge(Comparable[]arr,int low,int middle,int high):From index low To index middle As a subgroup, from the index mid+1 To index high For another subgroup, put in the array arr The data in these two subgroups are merged into an ordered large group (from the index) low To index high);4.private static boolean greater(Comparable a,Comparable b);judge a Greater than b;5.private static boolean exchange(Comparable[] arr,int a,int b);exchange arr In, index a And index b Value at; member variable: 6.private static Comparable[] temp: This is a temporary array;

code:

/** * 5.Merge sort * sort the elements in the array arr; *///Define a temporary array to store elements (which can be understood as exchanging space for time) private static Comparable[] temp;public static void mergeSort(Comparable[] arr) {/ / initialize a temporary array with a length of arr.length temp = new comparable [arr.length] ; / / define the index source and end. Int Low = 0; int high = arr.length - 1; / / call overloaded mergeSort(arr, low, high);} /*** sort the elements between index low and index high in array arr; * @ param arr array to be split * @ param low index header to be split * @ param high index tail to be split * / private static void mergeSort(Comparable[] arr, int low, int high) {/ / perform security check if (high < = low) {return;} / / group from low to high (for example, 5-9 is divided into 5-6; 7-8-9) int middle = low + (high - low) / 2; / / recursion, grouping mergesort (arr, low, middle); mergesort (arr, middle + 1, high); / / merging merge(arr, low, middle, high);} /*** from index low to index middle is a subgroup, and from index mid+1 to index high is another subgroup * merge the data in the two subgroups of arr in the array into an ordered large group (from index low to index high) ** @ param arr array to be split * @ param low index header to be split * @ param middle index * @ param high index tail to be split * / private static void merge(Comparable[] arr, int low, int middle, int high) {/ / define three pointers I, P1, P2, int i = low; int P1 = low; int P2 = middle + 1; / / compare the element sizes of the indexes pointed to by the two pointers, and put the small ones in the temp temporary array while (P1 < = middle & & P2 < = high) {if (greater (arr [P1], arr [P2]) {/ / P1 > P2, put P2 temp [i + +] = arr [P2 + +];} else {/ / put P1 temp [i + +] = arr [P1 + +];}} / / if one of the pointers has finished, loop another small array into the temp array; while (P1 < = middle) {temp [i + +] = arr [P1 + +];} while (P2 < = high) {temp [i + +] = arr [P2 + +];} / / put the temp array back to the original array for (int j = low; j <= high; j++) {        arr[j] = temp[j];    }}

     Time complexity analysis of merge sort

(you can see it if you have enough energy. You can skip it if you see some difficulties here. It doesn't matter if you don't understand it for the time being):

     Take the most pessimistic case, that is, complete reverse order, to calculate the time complexity:

     If an array {8,7,6,5,4,3,2,1} has 8 elements in total, it should be split: log2(8) times = 3 times, that is, there are 3 layers in total;

     If there are 2^f=4 subarrays in layer f=2, it is necessary to compare and merge twice;

     That is, the elements of layer F have 2^f sub arrays;

     The length of each subarray is 2^(3-f);

     Merge after comparing 2^(3-f) times at most;

     The maximum number of subarrays required for each layer * the number of times required for each subgroup=   2^f*2^(3-f)=2^3 = 8;

     Then the total number of three floors is 3 * 2 ^ 3 = 24;

Derivation and calculation process: (handwritten derivation is required)

     Assuming that the number of elements is N, it is necessary to split log2(N) times, with a total of log2(N) layers;

     The number of times that all layers need to be exchanged is:

    =log2(N)*2^(log2(N)) = log2(N)*N

     It's a little windy here. You have to calm down and deduce it well, but once you figure it out, you won't forget it;

     According to the big O derivation rule, the time complexity of final merging and sorting is: O(NlogN);

three point six     Quick sort

     First step      What is quick sort?

     The quick sort algorithm realizes sorting through multiple comparisons and exchanges. The sorting process is as follows:  

(1) Firstly, an element is randomly selected as the boundary value, and the array is divided into left and right parts through the boundary value.

(2) Collect data greater than or equal to the boundary value to the right of the array, and data less than the boundary value to the left of the array. At this time, all elements in the left part are less than or equal to the boundary value, while all elements in the right part are greater than or equal to the boundary value.

(3) Then, the data on the left and right can be sorted independently. For the array data on the left, you can take another boundary value and divide this part of the data into left and right parts. Similarly, place the smaller value on the left and the larger value on the right. The array data on the right can also be processed similarly.

(4) By repeating the above process, we can see that this is a recursive definition. After the left part is sorted recursively, the right part is sorted recursively. When the data of the left and right parts are sorted, the sorting of the whole array is completed

After understanding the official definition this time, continue to read the diagram. No picture, Say J8;

     Step 2      Quick sort algorithm diagram

     Requirement: a string of arrays: {6,1,2,7,9,3,4,5,8}. The results are required to be sorted from small to large;

Generally, the first element is selected as the reference element, which is 6 in index 0;

And make the element larger than 6 move to the right of the sequence and the element smaller than 6 move to the left of the sequence, so as to split the sequence into two parts. Then, by analogy, the first element will be selected as the reference element for the two parts after splitting, and the above steps will be repeated until it can not be divided again;

Add remarks:

Detailed explanation of the first round of divide and conquer (red box) enlargement: (select 6 at index 0 as the reference element):

The original number is as follows:

The first step is to move the right pointer one bit to the left

(-- right), and then compared with the reference element, 6 < 8;

Step 2: because 6 < 8, the right pointer continues to move one bit to the left (- - right), and then compares it with the benchmark element. 6 > 5, yeah! Find the element smaller than the benchmark element ~;

Step 3: because the right pointer finds an element smaller than the reference element, switch to the left pointer, move it one bit (+ + left) to the right, and then compare it with the reference element, 6 > 1;

Step 4: because the left pointer does not find an element larger than 6, left continues to move one bit (+ + left) to the right, and then compares it with the reference element, 6 > 2;

Step 5: similarly, left continues to move one bit (+ + left) to the right, and then compares it with the reference element, 6 < 7; Yeah! Find the element larger than the benchmark element ~;

Step 6: since both the left pointer and the right pointer have found the target element, start exchanging their positions;

Step 7: after the exchange, switch to the right pointer and move it one bit to the left. Compare it with the benchmark element, 6 < 4, and find the element smaller than the benchmark;

Step 8: switch to the left pointer and move it one bit to the right. Compare: 9 > 6, find the element larger than the benchmark element;

Step 9: exchange elements of left and right pointers;

Step 10: switch to the right pointer and move it one bit to the left. Compare: 6 > 3, find the element smaller than the benchmark element;

Step 11: switch to the left pointer and move it one bit to the right. It is found that left and right coincide. The trigger mechanism: exchange with the reference element;

After the exchange, the result looks like this ~~

Step 12: with reference element 6 as the center, cut two small groups left and right to carry out the next round of split sorting, and the original reference element does not participate in the next round of divide and conquer; After the first round of partition, the follow-up was similar;

Note: there are several ways to implement the code of this algorithm;

     The third step is to realize quick sorting by handwritten code

API to be implemented:

Member method:

1.public static void sort(Comparable[]arr):Pair array arr Sort the elements within; two.private static void sort(Comparable[]arr,int low,int high):Pair array arr Index in low To index high Sort the elements between; three.private static int partition(Comparable[]arr,int low,int middle,int high):From index low To index middle As a subgroup, from the index mid+1 To index high For another subgroup, put in the array arr The data in these two subgroups are merged into an ordered large group (from the index) low To index high);4.private static boolean greater(Comparable a,Comparable b)
5.private static boolean exchange(Comparable[] arr,int a,int b);exchange arr In, index a And index b Value at;

code:

/** * 6.Quick sort * @ param arr */public static void quickSort(Comparable[] arr) {    //Initialize the temporary array with the length of arr.length temp = new comparable [arr.length]// Define int Low = 0 at the source and end of the index; int high = arr.length - 1;    // Call overloaded quickSort(arr, low, high);}private static void quickSort(Comparable[] arr, int low, int high) {/ / do the security check if (high < = low) {return;} / / you need to group the elements from low to high in the array, including the left and right subgroups; int partition = partition(arr, low, high); / / make the left subgroups orderly (partition - 1 is because the critical value does not participate in sorting) quickSort(arr, low, partition - 1); / / make the right subgroup orderly quickSort(arr, partition + 1, high);} / * * * the incoming arr needs to be divided into two groups * * @ param arr the ARR to be grouped * @ param low packet start index * @ param high packet end index * @ return returns a new critical point * / private static int partition (comparable []) Arr, int low, int high) {/ / the critical boundary value is Comparable key = arr[low]; / / two pointers are defined to point to the next position of the minimum index and the maximum index respectively. Int left = low; int right = high + 1; / / scan the segmentation while (true) {/ / scan from right to left to find the element smaller than the benchmark and stop while (greater (arr [-- right]) , key) {/ / security check if (right = = low) {break;}} / / scan from left to right to find elements larger than the benchmark and stop while (greater(key, arr[++left]) {/ / security check if (left = = high) {break;}} //If (right < = left) {exchange (arr, low, right); break;} else {/ / exchange (arr, left, right);}} return right;}

     The derivation process of time complexity is similar to merging and sorting   : After each round of split and divide, the original array will be split into two parts, and then it will continue to be split into two parts in the next round until it can no longer be split. The array needs to be traversed once for each round of comparison and exchange, so O(n). On average, this traversal will require log(n), so~

    F(N)=O(NlogN);

4. Summary

  1. Learning algorithms, the thinking process is more important than the results. Of course, only when the code is implemented can it become your own real Kung Fu!

  2. If I really want to learn a certain technology well, go to read a book, although I am also writing bloggers of official account, I still strongly Amway to read books. If I really can not see it, I will read videos in thematic units, then read books, in short, I must read books.

  3. In fact, there are many loopholes in many code writing methods in this article, that is, some special cases are not considered very comprehensively. For example, in quick sorting, the element at the first position of each sub array is used as the reference element, and the time complexity is higher in the case of complete reverse order; In addition to using recursion, you can also use stack to implement these sorting algorithms, so that they can be completed from the lower level, and so on. There are many problems that need to be optimized; However, as an introduction, this article is enough;

Tags: Java Algorithm data structure

Posted on Fri, 03 Dec 2021 18:49:34 -0500 by infomamun