Divide and conquer law and merge sort, divide and conquer law merge sort
This article references introduction to algorithms.
Rule separation policy
To solve a given problem, an algorithm needs to recursively call itself once or multiple times to solve the relevant subproblems. This algorithm usually uses a divide policy. The sub-governance mode has three steps on each layer recursion:
> Decomposition: breaking down the original problem into a series of subproblems
> Solution: recursively solve each subproblem. If the sub-problem is small enough, solve it directly.
> Merge: Merge the sub-problem results into the solution of the original problem.
Merge Sorting (Merge Sorting)
The key to merging and sorting is to merge two adjacent subsequences so that they become a new sorted sequence. If the new sequence is the array to be sorted, the sorting is complete. Therefore, we need to recursively divide the original sequence into several subsequences. The smallest subsequence of the straight track has only one element, and then merge the subsequences in sequence to obtain the sorted original sequence. The first problem we need to solve is: Suppose There Is A subsequence A [p... q] and subsequence [q + 1... r] is a sorted subsequence. How can we merge them into a subsequence in order?
Merge two subsequences
We can use playing cards for simulation. Place the minimum number of cards on the top of the two stacks in sequence, and the cards are facing up.
> Step 1: Put the two smaller ones on the table.
> Step 2: Compare the obtained cards and the two stacked cards respectively. Repeat the first step and follow the previous card. Until a heap is finished.
> Step 3: place the remaining heap from top to bottom on the table, following the previous card.
As you can see, we can design the following code according to the problem requirement (orange:
Void merge (int ar [], int p, int q, int r, int temp []) {// convert ar [p... q] and ar [q + 1... r] merge to temp [p... r], temp memory allocated by external int I = p, j = q + 1, k = 0; while (I <= q & j <= r) {if (ar [I] <ar [j]) temp [k ++] = ar [I ++]; else temp [k ++] = ar [j ++];} while (I <= q) // If ar [p .. q] temp [k ++] = ar [I ++]; while (j <= r) // If ar [q + 1 .. r] temp [k ++] = ar [j ++]; for (k = 0; k <= (r-p); k ++) // assign the merged subsequence to the original sequence ar [p... r] ar [p + k] = temp [k];}
For Merge Sorting, the second problem we need to solve is: how can the original sequence become an ordered sequence?
Sequence the original sequence with the sub-Governance Policy
We can divide the original sequence into two sub-sequences, and then divide the two sub-sequences into the other four sub-Sequences Until they can no longer be decomposed. Then merge two adjacent subsequences until they cannot be merged. Here we will refer to a picture on the network and modify it to illustrate this principle.
As mentioned above, to solve a given problem, an algorithm needs to call itself recursively once or multiple times to solve the related subproblems. This algorithm usually uses a divide policy. Therefore, we can use the divide and conquer policy to solve the problem by calling a function recursively. We can write the code like this:
Void mergesort (int ar [], int head, int end, int temp []) {if (head <end) {// condition: int middle = (head + end)/2 until it cannot be split; // locate the mergesort (ar, head, middle, temp) Point of the binary original sequence ); // left subsequence sorting mergesort (ar, middle + 1, end, temp); // right subsequence sorting merge (ar, head, middle, end, temp ); // merge the two subsequences }}
By analyzing the above code, we can mark the execution sequence (we recommend opening in a new window) to verify the correctness of the algorithm. At the same time, you can also prove through a method similar to the "loop-free mode:
Complete code
At this point, all the problems of Merge Sorting have been solved. We provide the complete code without comments (the empty comments after memory allocation are signs, reminding you to release the memory in time.
1 # include <stdio. h> 2 # include <stdlib. h> 3 # include <conio. h> 4 # include <time. h> 5 6 void mergesort (int [], int []); 7 void merge (int [], int, int []); 8 9 int main (int argc, char * argv []) {10 int * ar, * temp; 11 int n = 10, I; 12 13 if (! (Ar = (int *) malloc (size_t) n * sizeof (int) // 14 exit (EXIT_FAILURE); 15 if (! (Temp = (int *) malloc (size_t) n * sizeof (int) // 16 exit (EXIT_FAILURE); 17 18 srand (unsigned int) time (NULL); 19 for (I = 0; I <n; I ++) {20 ar [I] = rand () % 1000; 21 printf ("%-4d", ar [I]); 22} 23 24 mergesort (ar, 0, n-1, temp ); 25 26 printf ("\ n after merging and sorting: \ n"); 27 for (I = 0; I <n; I ++) 28 printf ("%-4d ", ar [I]); 29 30 free (temp); 31 free (ar); 32 33 _ getch (); 34 return 0; 35} 36 37 void mergesort (int ar [], int head, int end, int temp []) {38 if (head <end) {39 int middle = (head + end)/2; 40 mergesort (ar, head, middle, temp); 41 mergesort (ar, middle + 1, end, temp ); 42 merge (ar, head, middle, end, temp); 43} 44} 45 46 void merge (int ar [], int p, int q, int r, int temp []) {47 int I = p, j = q + 1, k = 0; 48 while (I <= q & j <= r) {49 if (ar [I] <ar [j]) 50 temp [k ++] = ar [I ++]; 51 else52 temp [k ++] = ar [j ++]; 53} 54 while (I <= q) 55 temp [k ++] = ar [I ++]; 56 while (j <= r) 57 temp [k ++] = ar [j ++]; 58 59 for (k = 0; k <= (r-p); k ++) 60 ar [p + k] = temp [k]; 61}MergeSort
The following is an entry function. You only need to pass the array name and size to the mergesort () function in the main () function.
1 # include <stdio. h> 2 # include <stdlib. h> 3 # include <conio. h> 4 # include <time. h> 5 6 void mergesort (float *, int); 7 void _ mergesort (float *, int, int, float *); 8 void merge (float *, int, int, int, float *); 9 10 int main (int argc, char * argv []) {11 float * ar; 12 int n = 10, I; 13 14 if (! (Ar = (float *) malloc (size_t) n * sizeof (float) // 15 exit (EXIT_FAILURE); 16 17 srand (unsigned int) time (NULL); 18 for (I = 0; I <n; I ++) {19 ar [I] = (float) (rand () % 499 )) /(float) (rand () % 11 + 1); 20 printf ("%-6.3g", ar [I]); 21} 22 23 mergesort (ar, n); 24 25 printf ("\ n after merging and sorting: \ n"); 26 for (I = 0; I <n; I ++) 27 printf ("%-6.3g", ar [I]); 28 29 free (ar); 30 31 _ getch (); 32 return 0; 33} 34 35 void merge Sort (float * ar, int size) {36 if (size> 0) {37 float * temp; 38 if (! (Temp = (float *) malloc (size_t) size * sizeof (float) // 39 exit (EXIT_FAILURE); 40 _ mergesort (ar, 0, size-1, temp); 41 free (temp); 42} 43} 44 45 void _ mergesort (float * ar, int head, int end, float * temp) {46 if (head <end) {47 _ mergesort (ar, head, (head + end)/2, temp); 48 _ mergesort (ar, (head + end) /2 + 1, end, temp); 49 merge (ar, head, (head + end)/2, end, temp ); 50} 51} 52 53 void merge (float * ar, int p, int q, int r, float * temp) {54 int I = p, j = q + 1, k = 0; 55 while (I <= q & j <= r) {56 if (ar [I] <ar [j]) 57 temp [k ++] = ar [I ++]; 58 else59 temp [k ++] = ar [j ++]; 60} 61 while (I <= q) 62 temp [k ++] = ar [I ++]; 63 while (j <= r) 64 temp [k ++] = ar [j ++]; 65 66 for (k = 0; k <= (r-p); k ++) 67 ar [p + k] = temp [k]; 68}Better MergeSort