[C ++] sorting templates (including C ++ template code)
Sorting TEMPLATE 1. Insert sorting features: stable sort, In-place sort optimal complexity: when the input array is sorted, the complexity is O (n ), in this case, fast sorting will produce O (n ^ 2) complexity. Worst complexity: when the input array is in reverse order, the complexity is O (n ^ 2) Insert sorting is more suitable for "arrays with few elements ".
Pseudocode:
C ++ template:
template
void Insertion_Sort(T *array, size_t length) { if (length <= 1) { return; } else { for (int i = 1; i != length; i++) { int j = i - 1; T key = array[i]; while (j >= 0 && array[j] > key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } }}
Verify the correctness of the algorithm:
Cycle unchanged: before each cycle starts, A [1... I-1] contains the original A [1... I-1] elements, sorted.
Initial: I = 2, A [1... 1] sorted, true.
Persistence: Before the iteration starts, A [1... I-1] is sorted, and the purpose of the loop body is to insert A [I] into A [1... In I-1, make A [1... I] sorting, so before the start of the next iteration, I ++, So now A [1... I-1] Arranged order, so keep the cycle unchanged.
End: The Last I = n + 1, and A [1... N] has been sorted, while A [1... N] is the entire array.
Ii. Bubble sorting features: stable sort and In-place sort ideas: the small ones come out first, just like bubbles In the water, and the big ones come out later. Worst run time: O (n ^ 2) Best run time: O (n ^ 2) (of course, you can also make improvements to make the best run time O (n ))
Pseudocode:
C ++ template:
template
void Bubble_Sort(T *array, size_t length) { for (int i = 0; i != length - 1; i++) { for (int j = 0; j + i != length - 1; j++) { if (array[j] > array[j + 1]) { T temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } }}
Verify the correctness of the algorithm:
The inner loop of Line 4-6 is first proved by the two non-variant cycles, and then the outer loop is proved.
Inner cycle unchanged: before each cycle starts, A [j] is A [j... N] is the smallest element.
Initial: j = n, so A [n] is A [n... N.
Persistence: When the loop starts, it is known that A [j] is A [j... The smallest element of n, compare A [j] with A [J-1], and place the smaller one in the J-1 position, so it can be indicated that A [J-1] is A [J-1... N] is the smallest element, so the cycle remains unchanged.
Termination: j = I. It is known that A [I] is A [I... N] indicates the minimum element.
Next we will prove that the External Loop is not changed: before each loop, A [1... I-1] contains the smallest I-1 element in A, sorted: A [1] <= A [2] <=... <= A [I-1].
Initial: I = 1, so A [1. 0] = NULL, so it is true.
Persistence: When the loop starts, A [1… is known... I-1] is the smallest I-1 element in A, and A [1] <= A [2] <=... <= A [I-1], according to the inner cycle not changing, the end of A [I] is A [I... N] is the smallest element, so A [1... I] contains the smallest I element in A, and A [1] <= A [2] <=... <= A [I-1] <= A [I]
Termination: I = n + 1, known as A [1... N] is the smallest n elements in A, and A [1] <= A [2] <=... <= A [n.
In question 2-2 of the Introduction to algorithms, I asked "which is faster for Bubble sorting and insertion sorting?
The average person replied, "It's almost the same, because the approximate time is O (n ^ 2 )".
But in fact, this is not the case. The insert sorting speed is directly the number of Reverse Order pairs, while the number of "exchanges" executed in Bubble Sorting is the number of Reverse Order pairs, therefore, the time for bubble sort execution is at least the number of Reverse Order pairs. ThereforeInsert sort execution time is at least faster than bubble sort.
3. Select the sorting feature: In-place sort and unstable sort. Idea: Find a minimum value each time. Best time: O (n ^ 2 ). Worst case time: O (n ^ 2 ).
Pseudocode:
C ++ template:
template
void Selection_Sort(T *array, size_t length) { for (int i = 0; i != length; i++) { int min = i; for (int j = i + 1; j != length; j++) { if (array[min] > array[j]) { min = j; } } T temp = array[i]; array[i] = array[min]; array[min] = temp; }}
Verify the correctness of the algorithm:
Cycle unchanged: A [1... I-1] contains the smallest I-1 elements in a, sorted.
Initial: I = 1, A [1... 0] = NULL, so it is true.
Persistence: Keep the cycle unchanged before an iteration starts, that is, A [1... I-1] contains the smallest I-1 element in A, sorted, then after entering the loop body, the program from A [I... Locate the minimum value in n] At A [I], so A [1... I] contains the smallest I element in A and has been sorted, while I ++, so before the next cycle, keep the cycle unchanged: A [1 .. i-1] contains the smallest I-1 elements in a, sorted.
Termination: I = n, known as A [1... N-1] contains the smallest I-1 elements in a, sorted, so the elements in A [n] are the largest, so A [1... N] It has been sorted and verified.
Iv. Merge Sorting features: stable sort and Out-place sort ideas: Use the divide and conquer method to solve sorting problems. Worst case run time: O (nlgn) Best run time: O (nlgn)
Divide and conquer LAW Introduction: Divide and conquer law is to divide the original problem into multiple independent subproblems, and the form of these subproblems is similar to that of the original problem, but the scale is reduced, after the sub-problem is solved, the combined results constitute the solution of the original problem.
The sub-governance method usually involves three steps: Divide (Steps for decomposing subproblems) and Conquer (Steps for solving subproblems recursively) and Combine (Steps to merge the subproblem into the original problem after the subproblem is solved ).
Assume that Divide requires f (n) time, Conquer is decomposed into B Sub-problems, and the sub-problem size is a. Combine requires g (n) time, the recursion is:
T (n) = bT (n/a) + f (n) + g (n)
Introduction to algorithms Question 4-3 (parameter transfer) can be used to evaluate the understanding of divide and conquer methods.
For example, in merge Sorting, the Divide step is m = (p + q)/2, so it is O (1), and the Combine step is the merge () function, the Conquer step is divided into two subproblems, And the subproblem size is n/2. Therefore:
Recursive form of Merge Sorting: T (n) = 2 T (n/2) + O (n)
There are three recursive methods:
(1) replacement method: it is mainly used to verify the complexity of recursive expressions. (2) recursive tree: It can roughly estimate the complexity of the recursive formula. After estimation, it can be verified by replacement. (3) Main Theorem: used to solve some common Recursive formulas.
Pseudocode:
C ++ template:
template
void Merge(T *sourceArray, T *temp, int Start_Index, int Mid_Index, int End_Index) { int i = Start_Index, j = Mid_Index + 1, k = Start_Index; while (i != Mid_Index + 1 && j != End_Index + 1) { if (sourceArray[i] > sourceArray[j]) { temp[k++] = sourceArray[j++]; } else { temp[k++] = sourceArray[i++]; } } while (i != Mid_Index + 1) { temp[k++] = sourceArray[i++]; } while (j != End_Index + 1) { temp[k++] = sourceArray[j++]; } for (int i = Start_Index; i != End_Index + 1; i++) { sourceArray[i] = temp[i]; }}template
void Merge_Sort(T *sourceArray, T *temp, int Start_Index, int End_Index) { if (Start_Index < End_Index) { int Mid_Index = (Start_Index + End_Index) / 2; Merge_Sort(sourceArray, temp, Start_Index, Mid_Index); Merge_Sort(sourceArray, temp, Mid_Index + 1, End_Index); Merge(sourceArray, temp, Start_Index, Mid_Index, End_Index); }}
Merge Sorting of C ++ linked list:
// Sort and merge the linked list. Void upload list: sort (void) {if (this-> size ()> 1) {node * fast = this-> head; node * slow = this-> head; please list li_left; please list li_right; li_left.head = this-> head; while (fast! = NULL & fast-> next! = NULL) {li_left. _ size ++; fast = fast-> next; slow = slow-> next;} li_left.tail = slow-> prev; li_left.tail-> next = NULL; li_right.head = slow; li_right.head-> prev = NULL; li_right.tail = this-> tail; li_right. _ size = this-> _ size-li_left. _ size; this-> head = NULL; this-> tail = NULL; li_left.sort (); li_right.sort (); node * pointer_left = li_left.head; node * pointer_right = li_right.head; node * p Ointer_head = NULL; node * pointer_tail = NULL; while (pointer_left! = NULL & pointer_right! = NULL) {node * temp; if (pointer_left-> data <= pointer_right-> data) {temp = pointer_left; pointer_left = pointer_left-> next;} else {temp = pointer_right; pointer_right = pointer_right-> next;} if (pointer_head = NULL) {pointer_head = pointer_tail = temp;} else {pointer_tail-> next = temp; temp-> prev = pointer_tail; pointer_tail = temp;} pointer_head-> prev = NULL; pointer_tail-> next = NULL;} While (pointer_left! = NULL) {pointer_tail-> next = pointer_left; pointer_left-> prev = pointer_tail; pointer_tail = pointer_left; pointer_left = pointer_left-> next;} while (pointer_right! = NULL) {pointer_tail-> next = pointer_right; pointer_right-> prev = pointer_tail; pointer_tail = pointer_right; pointer_right = pointer_right-> next;} this-> head = pointer_head; this-> tail = pointer_tail; li_left.head = li_left.tail = NULL; li_right.head = li_right.tail = NULL ;}
Example:
Q: What are the disadvantages of Merge Sorting? <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Response + response/1bzkoaM8L3A + response/bHIv + zFxbTzoaM8L3A + response + KO/PC9wPg0KPHA + tPCjur7NysfU2sr91 + response = "5 quick sorting"> 5. Fast sorting
Algorithm introduction:
Set the array to be sorted to A [0]... A [N-1], first randomly select A data (usually the first number of the array) as the key data, and then put all the smaller than it before it, all the numbers larger than it are placed behind it. This process is called a fast sorting. It is worth noting that quick sorting is not a stable sorting algorithm, that is, the relative positions of multiple identical values may change at the end of the algorithm.
The quick sorting algorithm is as follows:
1) set two variables I, j, sorting start: I = 0, j = N-1;
2) Take the first array element as the key data and assign it to the key, that is, key = A [0];
3) search forward from j, that is, search forward from the back (j-), find the first value less than the key A [j], SWAps A [j] And A [I;
4) Search backward from I, that is, search backward from the beginning (I ++), find the first A [I] greater than the key, swap A [I] with A [j;
5) Repeat steps 3rd and 4 until I = j; (in step 3 and 4, no matching value is found, that is, in step 3, A [j] is not smaller than the key, in 4, when A [I] is not greater than the key, the value of j and I is changed so that j = J-1, I = I + 1 until it is found. Find the value that meets the condition. When switching, the position of the j pointer remains unchanged. In addition, the process I = j must be exactly when I + or j-is completed, and the loop ends at this time ).
QUICK_SORT(A,p,r)if p
C ++ template:
template void Quick_Sort(T *array, int Start_Index, int End_Index) { if (End_Index >= Start_Index) { int first = Start_Index; int last = End_Index; T key = array[first]; while (first < last) { while (first < last && array[last] >= key) { last--; } array[first] = array[last]; while (first < last && array[first] <= key) { first++; } array[last] = array[first]; } array[first] = key; Quick_Sort(array, Start_Index, first - 1); Quick_Sort(array, first + 1, End_Index); }}