# Include <iostream> # include <cstdlib> # include <ctime> # define M 20 using namespace std; static int count_insert = 0; static int count_partion = 0; typedef struct index {int left; int right;} index; void swap (int & small, int & big) {int temp = small; small = big; big = temp ;} /* | insert sorting in brief: | cur = 1-> right indicates the part to be sorted, and pre indicates the part to be sorted. | First store the first position element arr [cur] into tmp, then compare the arr [pre] and arr [cur], | if arr [cur] <arr [pre] is to be sorted, arr [pre + 1] = arr [pre] is shifted. | the purpose of the shift is to shift small elements, here, arr [cur] is placed in the proper position of the sorted part. | in this way, each arr [cur] will be overwritten by arr [pre, this is why tmp = arr [cur] was just started | then place tmp at the location of arr [pre] */void insert_sort (int arr [], int left, int right) {int tmp, cur, pre; for (cur = 1; cur <right; cur ++) {pre = cur-1; tmp = arr [cur]; while (tmp <arr [pre] & pre> = 0) {arr [pre + 1] = ar R [pre]; pre --;} arr [pre] = tmp;} count_insert + = 1;}/* | briefly describes the algorithm concept: | when there are a large number of repeated elements, obviously, it can be controlled to improve efficiency. | In a division loop, elements at I and j are exchanged whenever the scanning pointer (I, j) is stopped. | it also determines whether the element at the pointer is equal to the Division element base; | if arr [I] is equal to the Division element, the elements on the left of the array are exchanged. | if arr [j] is equal to the Division element, then, the elements on the Right of arr [j] and array are used. | Finally, move the areas at both ends of the array to the center of the array that are equal to the partition element. */Index partion (int arr [], int left, int right) {int I, j; int pleft, pright; int tag, base; index p; if (left> right) exit (-1); I = left-1, j = right; pleft = left-1, pright = right; base = arr [right]; // @ _ 1 for (;) {while (I <j & arr [++ I] <base ); while (I <j & arr [-- j]> base) if (j <= left) break; if (j = I) break; swap (arr [j], arr [I]); // @ _ 2if (arr [I] = base) {pleft + = 1; swap (arr [I], arr [pleft]);} if (arr [j] = base) {pright-= 1; swap (arr [j], arr [pright]); // @ _ 3 }}// for swap (arr [right], arr [I]); // @ _ 4j = I-1; I = I + 1; for (tag = left; tag <= pleft; tag ++, j --) swap (arr [tag], arr [j]); for (tag = right-1; tag >=pright; tag --, I ++) swap (arr [tag], arr [I]); // @ _ 5 p. left = j, p. right = I; count_partion + = 1; return p;}/* | if the length of the subfile after division is less than 20, sort it by insert. | otherwise, sort it quickly. | After the recursive division of N, a large number of small files, such as the length of arr [0-> 10], will be generated. | it is obviously not worth the cost to continue the quick sorting. */Void quick_sort (int arr [], int left, int right) {if (left <right) {if (right-left) <= M) insert_sort (arr, left, right); else {index sec = partion (arr, left, right); quick_sort (arr, left, sec. left); quick_sort (arr, sec. right, right) ;}} int main () {const int size = 500; static int s [size]; srand (unsigned int (time (NULL ))); for (int I = 0; I <size; I ++) s [I] = rand () % 100; quick_sort (s, 0, size-1 ); for (I = 0; I <size; I ++) cout <s [I] <""; cout <endl; cout <"call insert_sort" <count_insert <"times" <endl; cout <"call partion_sort" <count_partion <"times" <endl; cin. get (); return 0 ;}