Introduction to algorithms Chapter 1 quick sorting

Source: Internet
Author: User
I. Concepts

Fast sorting is based on the divide and conquer mode. After a number is selected as the principal component, all the numbers smaller than the principal component are placed on the left of the principal component, and the numbers greater than the principal component are placed on the right of the principal component, in this way, the data is divided into two groups. Then, the two groups are sorted in a fast manner.

The running time of the Quick Sort is related to the symmetry of the Division. The key is how to select the principal component.

In the worst case, the time complexity is O (n ^ 2). In the best case, the time is O (nlgn)

Ii. Procedures
# Include <iostream> using namespace STD; // output process void print (int * a, int Len) {for (INT I = 0; I <Len; I ++) {if (I) cout <''; else cout <" => A = {"; cout <A [I];} cout <'}' <Endl ;} /************************ 7.1 General fast schedule *********** *************************************/// divide int partition (int *, int P, int R) {// select a [R] as the principal element int x = A [R]; int I = p-1, J; For (j = P; j <r; j ++) {// if (a [J] <= x) {I ++; // switch swap (A [I], a [J]) larger than the principal component;} swap (A [I + 1], a [R]); // return the position of the final Principal Component return I + 1;} void quicksort (int * a, int P, int R) {If (P <R) {// based on a principal component, the array is divided into two parts. The left side is smaller than the principal component, and the right side is larger than the main element. Int q = partition (A, P, R ); // sort quicksort (A, P, q-1); quicksort (A, q + 1, R );}} /******************* 7.3 random fast rank *************** ***************************************/ // divide int randomized_partition (int *, int P, int R) {// randomly select a number as the principal component int I = rand () % (r-p + 1) + P; swap (A [R], A [I]); Return partition (A, P, R);} // sort in the same principle as normal fast sorting, the calling method is different. Void randomized_quicksort (int * a, int P, int R) {If (P <r) {int q = randomized_partition (A, P, R ); randomized_quicksort (A, P, q-1); randomized_quicksort (A, q + 1, R );}}

Iii. Description of quick sorting in exercise 7.1

7.1-1 A = {13 19 9 5 12 8 7 4 21 2 6 11 }=> A = {9 5 8 7 4 2 6 11 21 13 19 12} => A = {5 4 2 6 9 8 7 11 21 13 19 12 }=> A = {2 4 5 6 9 8 11 21 13 19 12 }=> = {2 4 5 6 9 8 7 11 21 13 19 12 }=> A = {2 4 5 6 7 8 9 11 21 13 19 12 }=> A = {2 4 5 6 7 8 9 11 21 13 19 12 }=> A = {2 4 5 6 7 8 9 11 12 13 19 21 }=> A = {2 4 5 6 7 8 9 11 12 13 19 21 }=> A = {2 4 5 6 7 8 9 11 12 13 19 21} 7.1-2 Return r7.1-2 modify part Ition (A, P, R), adds processing for a [I] = x. For data of a [I] = x, half is placed on the left side of X, and half is placed on the right side of X. // you can divide int partition (int * a, int P, int R) {// select a [R] as the principal element int x = A [R]; int I = p-1, J; bool flag = 0; For (j = P; j <r; j ++) {// if (a [J] <X | (A [J] = x & flag )) {I ++; // swap greater than the principal component to the right (A [I], a [J]); if (a [J] = x) Flag =! Flag ;}} swap (A [I + 1], a [R]); // return the position of the final Principal Component return I + 1;} 7.1-3partition () the specific process is as follows: (1) x <-A [R], O (1) (2) traversal array, O (N) (3) Exchange, O (1) therefore, if the running time is O (n) 7.1-4, modify partition (A, P, R) and change L4 to do if a [J]> = x
7.2 performance of fast sorting
7.2-1 see Introduction to algorithms 7.4.1. My method: T (n) = T (n-1) + O (n) T (n-1) = T (n-2) + O (n-1 )...... = ...... + ...... T (2) = T (1) + O (2) ---------------------- T (n) = T (1) + O (n) + O (n-1) + ...... + O (2) = O (N ^ 2) 7.2-2o (N ^ 2) 7.2-3 when array A contains different elements in descending order, each partition is divided into n-1 elements and 1 element, which is the worst case. Therefore, if the time is O (n ^ 2) 7.2-4, the basic ordered series is less efficient than the fast sorting. 7.2-5 if the number of elements in the first layer is n, it is divided into N (1-A) elements and Na elements. 0 <A <= 1/2 => Na <= N (1-A), so only N (1-A) is considered ). The number of elements at Layer T is Na ^ (t-1 ). Division ends when Na ^ (t-1) = 1. The solution t =-lgn/lg (1-A) + 1 is about-lgn/lg (1-A ). 7.2-6 refer
7.3 randomized version of quick sorting
7.3-1 randomization is not intended to improve the performance in the worst case, but to minimize the occurrence of 7.3-2 in the worst case, n elements are divided into n-1 and 1 each time, and 1 element does not need to be further divided. Therefore, in the case of O (n) times, it is best to divide each element from the middle, and recursive formula n (n) = 1 + 2 * n (n/2) = O (N)
7.4 Quick Sort Analysis
7.4-1 no definition of these symbols found 7.4-2 see Introduction to algorithms p88 best case division 7.4-3 order F (q) = Q ^ 2 + (n-q-1) ^ 2 = 2q ^ 2 + 2 (1-N) q + (n-1) ^ 2 This is a parabolic curve about Q and the opening is up. Therefore, the farther the value of Q is from the symmetry axis, the larger the value of F (q. The symmetry axis is Q =-B/2a = (n-1) /2 When q = 0 or Q = n-1 get the maximum value 7.4-4 See "Introduction to algorithms" P7.4.27.4-5 // 7.4-5 Use Insert sort to improve the fast rank int K = 4; // divide int partition (int * a, int P, int R) {// select a [R] as the principal element int x = A [R]; int I = p-1, J; bool flag = 0; For (j = P; j <r; j ++) {// if (a [J] <X | (A [J] = x & flag) {I ++; // switch the swap (A [I], a [J]) greater than the principal component to the right. If (A [J] = x) Flag =! Flag ;}} swap (A [I + 1], a [R]); // return the position of the final Principal Component return I + 1 ;} // fast sort void quicksort (int * a, int P, int R) {// sub-arrays with a length less than K are not sorted if (r-p> = K) {// based on a principal component, the array is divided into two parts. The left side is smaller than the principal component, and the right side is larger than the main element. Int q = partition (A, P, R ); // sort quicksort (A, P, q-1); quicksort (A, q + 1, R );}} // Insert the sorted void insertsort (int * a, int P, int R) {int I, j; for (I = p + 1; I <= r; I ++) {int temp = A [I]; j = I; while (A [J-1]> temp) {A [J] = A [J-1]; j --;} A [J] = temp ;}} void sort (int * a, int P, int R) {// first, perform a coarse-grained quicksort (A, P, R ); // Insert the sorting items one by one. insertsort (A, P, R );}

 

Iv. correctness of Hoare Division
7-1 correctness of Hoare division) A = {13 19 9 5 12 8 7 4 11 2 6 21 }=> A = {6 19 9 5 12 8 7 4 11 2 13 21 }=> A = {6 2 9 5 12 8 7 4 11 19 13 21 }=> A = {4 2 9 5 12 8 7 6 11 19 13 21 }=> A = {4 2 5 9 12 8 7 6 11 19 13 21 }=> A = {2 4 5 9 12 8 7 6 11 19 13 21 }=> A = {2 4 5 6 12 8 7 9 11 19 13 21 }=> A = {2 4 5 6 7 8 12 9 11 19 13 21 }=> A = {2 4 5 6 7 8 9 12 11 19 13 21 }=> A = {2 4 5 6 7 8 9 12 11 13 19 2 1} B) self-written, very messy, let's take a look at the main points to prove the following :( 1) do repeat j <-J-1 until a [J] <= X in the repeat, P <= j <= r when L6 is executed for the first time, and P <= j <= r when L6 is executed for the last time. Proof: 1. when L6 is executed for the first time, P <= j <= R. For differentiation, j '= J-1, J in L6 is represented by j. When you enter the while loop for the first time, j = R + 1, j '= R, and P <= j <= R. If it is not the first time to enter the while loop, j <= R and j> P. Because if J = P, if of the last while loop cannot pass, return has been returned. Therefore, P <= j <R-1, meet P <= j <= R. 2. when L6 is last executed, P <= j <= r, that is, it must be proved in a [p .. in R], there is a j 'that satisfies j' <= J and a [J] <= x. If j '= P is used to enter the while loop for the first time, in the previous while loop, the element in the past met the condition (2) do repeat I <I + 1 until a [I]> = X in the repeat, when l8 is executed for the first time, P <= I <= R. When l8 is executed for the last time, P <= I <= r proves that the method is similar to (1) c) according to B, the returned value P <= j <= R. Here we only need to prove J! = R if the loop of a [R]> X, L5, and L6 is not stopped when J = R, the return value is J! = R if a [R] <= X, the loop of L5 and L6 stops at J = R only when the while loop is started for the first time. Because it is the first time to enter the while loop, the loop of a [I] = A [p] = x, L7 and l8 will stop when I = P. Apparently, it will enter the while loop for the second time. At this time, j <R, so the return value is J! = RD) The question is wrong. It should be a [p .. each element in J] is less than or equal to a [J + 1 .. r] When each element ends, a [p .. all elements in I-1] are less than X, a [J + 1 .. r], where all elements are greater than X, Proposition e) int hoare_partition (int * a, int P, int R) {int x = A [p], I = p-1, j = R + 1; while (true) {do {J --;} while (A [J]> X); do {I ++ ;} while (A [I] <X); if (I <j) Swap (A [I], a [J]); else return J; print (, 12) ;}} void hoare_quicksort (int * a, int P, int R) {If (P <r) {int q = hoare_partition (A, P, R ); hoare_quicksort (A, P, q-1); hoare_quicksort (A, q + 1, R );}}

 

7-2 Another analysis of the fast Sorting Algorithm
A) 1 + 2 + ...... + N + 1 E [XI] = -------------------- = ------- n 2b)

 

7-3 stooge sorting
Void stooge_sort (int * a, int I, Int J) {if (a [I]> A [J]) Swap (A [I], a [J]); if (I + 1> = J) return; k = (J-I + 1)/3; stooge_sort (A, I, j-k); stooge_sort (, I + k, J); stooge_sort (A, I, j-k);} the following content to http://blog.csdn.net/zhanglei8893a) for Array a [I... j]. The stooge-sort algorithm divides the array into three equal parts, represented by A, B, and C, respectively. Steps 6-8 are similar to the idea of Bubble sorting. It takes two steps: step 6 and step 7 of the first trip swap the largest part 1/3 to step 2 of the second trip C swap the largest part 8th except C to the remaining 1/3 of B located in, in this case, the entire array a [I... j. B) It is easier to write the recursive T (n) = 2 T (2n/3) + substring (1) of stooge-sort in the worst case) according to the main law, T (n) = n ^ 2.71c can be obtained. In the worst case, the running time of various sorting algorithms is insert sorting and fast sorting: Sort (N ^ 2) heap sorting and Merge Sorting: Compared with the classic sorting algorithm, the stooge-sort algorithm has very poor performance. These lifelong professors can only say that they are falsely named ^_^.
7-4 stack depth in quick sorting
a)void QuickSort2(int *A, int p, int r){while(p < r){int q = Partition(A, int p, r);QuickSort2(A, p, q-1);p = q + 1;}}b)A = {1, 2, 3, 4, 5, 6}c)void QuickSort3(int *A, int p, int r){while(p < r){int q = Partition(A, int p, r);if(r-q > q-p){QuickSort3(A, p, q-1);p = q + 1;}else{QuickSort3(A, q+1, r);r = q - 1;}}}

7-5 Division of "three numbers in the middle"

A) n numbers any three different numbers can be obtained in total C (3, n). If x = A' [I] is required, it must be in a' [1 .. take a number in the I-1, In a' [I + 1 .. n] to take a number of common (I-1) * (N-I) (I-1) * (N-I) 6 * (I-1) * (N-I) pi = --------------- = ------------------- C (3, n) N * (n-1) * (n-2) B) in general implementation, Pi = 1/N. When N-> is positive infinity, the limit is 0. In this implementation, when I = (n + 1)/2, 3 (n-1) Pi = ---------, when n-> is positive infinity, the limit is 0 2n (n-2) c) There is no way to deal with such a mathematical problem. Ah, I didn't learn mathematics well before. d. I don't need to attach the program I wrote. // int getmid (int * a, int P, int R) {int A =-1, B =-1, C =-1; while (A <p) A = rand () % (R + 1 ); while (B <p) B = rand () % (R + 1); While (C <p) C = rand () % (R + 1 ); if (A [a]-A [B]) * (a [a]-A [c]) <= 0) return; if (A [B]-A [a]) * (a [B]-A [c]) <= 0) return B; if (A [c]-A [a]) * (a [c]-A [B]) <= 0) return C ;} // divide int partition (int *, Int P, int R) {// select a [R] as the principal component int M = getmid (A, P, R); swap (A [m], A [R]); int x = A [R]; int I = p-1, J; bool flag = 0; For (j = P; j <R; j ++) {// if (a [J] <X | (A [J] = x & flag) {I ++; // switch the swap (A [I], a [J]) greater than the principal component to the right. If (A [J] = x) Flag =! Flag ;}} swap (A [I + 1], a [R]); // return the position of the final Principal Component return I + 1 ;} // fast sort void quicksort (int * a, int P, int R) {// sub-arrays with a length less than K are not sorted if (r> P) {// based on a principal component, the array is divided into two parts. The left side is smaller than the principal component, and the right side is larger than the main element. Int q = partition (A, P, R ); // sort quicksort (A, P, q-1); quicksort (A, q + 1, R );}}

 

Fuzzy sorting of 7-6 pairs of intervals

See introduction to algorithms-fuzzy sorting of intervals in 7-6

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.