[Programming Pearl] Chapter 1 sorting (deep Optimization of insert sorting and quick sorting)

Source: Internet
Author: User

I. Overview

1) insert sorting

To locate a proper position, you must determine that the first element is smaller than T and the other element is larger than T. Insert T to the correct position.

It is critical to compare the relationship between a [J-1] And a [J ].


Isort1: if the final position is not reached, this element is exchanged with the element above it.

# Include <algorithm>

        for(int i=1;i<5;i++)for(int j=i;j>0&&a[j-1]>a[j];j--)                  swap(a[j-1],a[j]);
Isort2: replace library functions
 
int temp;for(int i=1;i<5;i++)for(int j=i; j>0 && a[j-1]>a[j]; j--)   {        temp=a[j];        a[j]=a[j-1];        a[j-1]=temp;       }

Isort3: reduces the number of moves

 
for(i=1;i<5;i++){t=a[i];for(j=i; j>0 && a[j-1]>t; j--)        a[j]=a[j-1];                 a[j]=t;        }

2) Fast sorting

Qsort1: O (nlog (n) time and O (logn) stack space
 
# Include "stdio. H "Void partition (int A [], int left, int right) {int I = left, j = right; int temp = A [I]; // record the position of the lower axis if (left> = right) // exit condition return; while (I <j) {While (I <J & temp <= A [J]) // find the first j --; A [I] = A [J]; // the smaller one is equal to the greater one (the later one will increase) [this trip will not be moved after the large one is moved to the front.] While (I <J & temp> = A [I]) // search from the left, find the first I ++; A [J] = A [I]; // large backward shift} A [I] = temp; // locate the correct position of the Axis partition (A, left, J-1); partition (A, J + 1, right);} int main () {int A [10] = {,}; partition (A,); For (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); Return 0 ;}

Qsort2: bidirectional division to avoid the worst case when all elements are equal

# Include <iostream> # include <algorithm> using namespace STD; void quictsort (int A [], int L, int U) {If (L> = u) return; int T = A [l]; // record axis int I = L; Int J = u + 1; for (;) {do I ++; while (I <= u & A [I] <t); // first I ++ and then judge the condition do j --; while (A [J]> T ); // J first -- then judge the condition if (I> J) // condition break for infinite loop exit; swap (A [I], a [J]); // each time a previous element is found, the element is equal to or greater than the axis, and the element is equal to or greater than the axis.} swap (A [L], a [J]); quictsort (A, l, j-1); quictsort (A, J + 1, U);} int main () {int A [10] = {,}; quictsort (, 0, 7); For (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); Return 0 ;}


Idea: An array composed of N identical elements has the best insertion sorting performance (the distance to which each element needs to be moved is 0), and the time complexity is O (n ). The performance of fast sorting is very bad. n-1 Division requires 0 (n) Time to remove an element, so the time complexity is O (n * n) the countermeasure is: Take two inner cycles, the first element is shifted to the right too small, when a large element is stopped, the second is shifted to the left, and the small element is stopped. Then switch. When the same element is encountered, stop scanning and exchange the values of a [I] And a [J. Worst time complexity O (nlogn)

Qsort3: using the number of random positions as the axis will optimize the fast sorting of arrays.
 
# Include <iostream> # include <algorithm> using namespace STD; void quictsort (int A [], int L, int U) {If (L> = u) return; swap (A [L], a [rand () % (u-l) + L]); // just write an article here int T = A [l]; int I = L; Int J = u + 1; for (;) {do I ++; while (I <= u & A [I] <t ); do J --; while (A [J]> T); if (I> J) break; swap (A [I], a [J]);} swap (A [L], a [J]); quictsort (A, L, J-1); quictsort (A, J + 1, U);} int main () {int A [10] = {,}; quictsort (A,); For (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); Return 0 ;}
 
 
 
[Knowledge point] method for generating random numbers within a range:
 
For example, a random number of [60-99] is generated.
The random number generated by using the rand () function starts from 0 (including 0). Let's think: [0,?] + 60 = [60, 99] is obvious ,? It should be 39. A random number [0, 39] can be generated as follows: rand () % 40.

# Include <iostream> using namespace STD; # include <cstdlib> # include <ctime> int main () {srand (Time (null )); // random numbers produced by different seeds are different for (INT I = 0; I! = 50; ++ I) {cout <rand () % 40 + 60 <Endl ;}}

Rand () % (end-Start) + start;

Note: Because the rand () function generates integers in the specified order, the same value is printed for each execution of the preceding statement, therefore, the random C language is not really random. Sometimes it is also called a pseudo-random number.

 
Ii. Exercise
2) The Fast Sorting Algorithm of lomuto is as follows:
# Include <iostream> # include <algorithm> using namespace STD; void quictsort (int A [], int L, int U) {If (L> = u) return; int M = L; // record axis for (INT I = L + 1; I <= u; ++ I) {if (a [I] <A [l]) // less than the axis swap (A [++ m], a [I]); // switch to the front to + + m to indicate that the position of the axis is moved backward} swap (A [L], a [m]); // locate the position of the axis and switch quictsort (, m-1); quictsort (a, m + 1, U);} int main () {int A [10] = }; quictsort (A, 0, 7); For (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); return 0 ;}
       
The algorithm after optimization using the sentry: (reduces the number of inner loop tests)
# Include <iostream> # include <algorithm> using namespace STD; void quictsort (int A [], int L, int U) {If (L> = u) return; int M = u + 1; // record axis int I = u + 1; do {While (A [-- I] <A [l]); // find a [I] swap (A [-- m], a [I]) that is larger than the axis. // swap the element larger than the axis to the following M -- m is the calculated element larger than the axis and then shifts left} while (I! = L); quictsort (A, L, s-1); quictsort (a, m + 1, U);} int main () {int A [10] = {3, 4, ,}; quictsort (A,); For (INT I = 0; I <8; I ++) printf ("% d \ n ", A [I]); Return 0 ;}

5) I did not fully understand the question
        
6) Select sorting
#include <iostream>#include <algorithm>using namespace std;void selectSort(int a[],int n){for(int i=0;i<n;++i){for(int j=i;j<n;++j){if(a[i]>a[j])swap(a[i],a[j]);}}}int main(){int a[10]={3,4,2,1,6,5,7,8};selectSort(a,7);for(int i=0;i<8;i++)            printf("%d\n",a[i]);return 0;}
Hill sorting: optimizing the selected sorting
# Include "stdio. H "Void shellsort (int A [], int N) {int K = n/2; // The first spacing is divided into two groups while (k> 0) {for (INT I = K; I <n; I ++) // compare the distance from the first value to n/2 {int T = A [I]; // Int J = I-K; // The first number of rows I = K while (j> = 0 & T <A [J]) // is the number below small? {A [J + k] = A [J]; j = J-K; // if it is exchanged, it will become negative.} A [J + k] = T ;} k = K/2 ;}} int main () {int A [9] = {,}; shellsort (A, 8 ); for (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); Return 0 ;}
 
9) Finding the K-small element in linear time
Idea: select a sort for fast sorting to divide the array. The value on the left is smaller than the limit, and the value on the right is greater than or equal to the limit. Therefore, we calculate the total number of Count values on the left that are less than the limit (plus the limit, if it is equal to K, it is exactly what we want. If it is greater than K, it means that the number of the smallest k is on the left, then recursion is performed on the left. Otherwise, on the right, it means that the number k-count on the right is what we want, and recursion is performed on the right.
Algorithm Implementation 1:

# Include <iostream> using namespace STD; inline void swap (int A [], int I, Int J) // inline function, swap two element locations {int temp = A [I]; A [I] = A [J]; A [J] = temp;} int partition (int A [], int P, int R) // The array is divided by limit a [R] {int Limit = A [R]; int low = p-1; int I; for (I = P; I <r; I ++) {if (a [I] <= condition) Swap (A, ++ low, I) ;} swap (A, ++ low, r); return low;} int rondompartition (int A [], int P, int R) {int I = P + rand () % (r-p + 1 ); // randomly select a partition to divide swap (A, I, R); Return partition (A, P, R ); // return axis position} int selectkmin (int A [], int P, int R, int K) {If (P = r) return a [p]; int q = rondompartition (A, P, R); int COUNT = Q-p + 1; // calculate a [p .. q] Number of elements if (k = count) // return a [Q]; else if (k <count) // return selectkmin (, p, Q-1, k); else // return selectkmin (A, q + 1, R, K-count) in the second half;} int main () {int A [] = {,}; int K = 3; cout <selectkmin (A, k) <Endl; return 0 ;}

 

Algorithm Implementation 2:

# Include "stdio. H "int getmink (int A [], int N, int K) {int S =-1, I = 0, j = n-1, temp; int beg = I; int end = J; while (s! = K) {beg = I; end = J; temp = A [I]; while (I <j) {While (I <J & A [J]> = temp) j --; A [I] = A [J]; while (I <J & A [I] <= temp) I ++; A [J] = A [I];} A [I] = temp; S = I; If (S = k) return a [k]; If (S> K) {I = beg; j --;} // search for if (S <k) {J = end; I ++;} on the left. // search for} int main () on the right () {int A [] = {2, 3, 4, 1, 5, 10, 9, 7, 8, 6}; int K = 3; printf ("the % d small element is: (starting from 0) \ n % d ", K, getmink (A, 10, k); Return 0 ;}

14) Algorithm Implementation:

# Include <iostream> # include <algorithm> using namespace STD; void quictsort (int A [], int U) {If (U <= 1) return; int m = 0; // record axis for (INT I = 1; I <= u; ++ I) {if (a [I] <A [0]) // less than the axis swap (A [++ m], a [I]); // switch to the front to + + m to indicate that the position of the axis is moved backward} swap (A [0], a [m]); // locate the position of the axis and switch quictsort (, m-1); quictsort (a + m + 1, u-m-1);} int main () {int A [10] = {,}; quictsort (, 7); For (INT I = 0; I <8; I ++) printf ("% d \ n", a [I]); Return 0 ;}

 

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.