The analysis and optimization of C + + fast sequencing _c language

Source: Internet
Author: User
Tags rand

I believe that the data structure and algorithm of the friends of the fast sort should not be unfamiliar, this article on the example of C + + rapid sequencing of the analysis and optimization, for C + + algorithm design has a good reference value. The specific analysis is as follows:

Introduction to a quick sort

A quick sort is a sort algorithm for an input array containing n numbers, and the worst-case runtime is theta (n2) [θ read as Theta]. Although the worst-case runtime is poor, fast sorting is often the best practical choice for sorting. This is because the average performance is fairly good: the expected elapsed time is theta (NLGN), and the constant factor implied in the theta (NLGN) notation is small. In addition, it can be sorted in place, and it works well in virtual memory environments.

As with the merge sort, the quick sort is also based on the partition rule (Divide and conquer):

Decomposition: Array a[p ... R] is divided into two (possibly empty) array a[p. Q-1] and A[Q+1..R], making a[p. Each element in Q-1] is greater than or equal to a[q] in less than equal to A[Q],A[Q+1..R. So the element A[q] is in its final position.

Workaround: Quick Sort by recursive invocation, a[p to the array of pairs ... Q-1] and A[Q+1..R] sort.

Merging: Because two arrays are in-place ordering, no merging is required, and the entire array is ordered.

Pseudo code is as follows:

PARTITION (A, P, r) 
  x = a[p] 
  i = p for 
  j=p+1 to R do 
    if A[J] <= x 
      Then i = i+1 
         Exchange (a[i],a[j ]) 
  Exchange (A[p], a[i]) return 
  i 
 
QUICKSORT (A, p, r) 
  if p < r 
    then q = PARTITION (A, p, R) 
       qui Cksort (A, p, q-1) 
       QUICKSORT (A, q+1, R) 

Second, performance analysis

1. Worst Case scenario

The worst-case scenario for a quick sort occurs when an array is ordered or in reverse order. In this case, one of the two regions resulting from the partitioning process has no elements and the other contains n-1 elements. The running time of the algorithm can be represented recursively as: t (n) = t (n-1) +t (0) +θ (n), and the solution of the recursive type is T (n) =θ (n^2). As you can see, the fast sort algorithm is not better than the insertion sort.

2, the best situation

If we are lucky enough to achieve the most balanced division in each partition, we will divide the array into N/2:N/2. The recursive formula obtained at this time is t (n) = 2T (N/2) +θ (n), according to the case of the principal theorem, two can obtain T (n) =θ (NLGN).

3. Average situation

Suppose one: The partitioning point in the quick row is very skewed, such as dividing the array into two 1/10:9/10 regions each time, what is the running time? The run time recursion is t (n) = t (N/10) +t (9N/10) +θ (n), and the recursive tree is used to solve T (n) =θ (NLGN). As you can see, when the dividing point is very skewed, the runtime is still Theta (NLGN).

Hypothesis Two: the division produced by partition has both "good" and "bad", they appear alternately. What is the average running time? The recursion at this time is (g indicates good,b):

G (n) = 2B (N/2) +θ (n)

B (n) = G (n-1) +θ (n)

Solution: g (N) = 2 (g (n/2-1) +θ (N/2)) +θ (n) = 2G (n/2-1) +θ (n) =θ (NLGN)

It can be seen that, when the good, the difference divides alternately appear, the fast row's running time is like all good division, still is θ (NLGN).

Three, the optimization of the fast row

As you can see from the above analysis, fast sorting is slow in the input order or reverse, and in the rest of the case it behaves well. If the input itself has been sorted, then it's bad. So how do we make sure that it gets better average performance for all the inputs? Quick sort in front we use the first element of the array as the main element by default. Assuming that elements in an array are randomly selected as primary, the run time of the row will not depend on the order of the input sequence. We call the fast ordering of randomly selected principal elements randomized Quicksort.

In a quick sort of randomization, instead of always selecting the first element as the primary, we randomly select an element from the array a[p...r and swap it with the first element. Because the main element element is randomly selected, we expect that the partitioning of the input array will be more symmetrical in the average case.

Pseudo code is as follows:

Randomized-partition (A, p, r) 
  i = RANDOM (P, R) 
  Exchange (A[p], a[i]) return 
  PARTITION (A, p, R) 
 
Randomized-quicksort (A, p, r) 
  if p < r 
    then q = randomized-partition (A, p, r) 
      Randomized-quicksort (A, p, q 1) 
      Randomized-quicksort (A, q+1, R) 

We perform the traditional fast sorting and randomization of the ordered sequences of 30,000 elements, and compare their elapsed time:

/************************************************************************* > File Name:QuickSort.cpp > Autho R:songlee ************************************************************************/#include <iostream> # 
 
include<cstdlib>//Srand rand #include <ctime>//clock_t clock using namespace std; 
  void swap (int &a, int &b) {int tmp = A; 
  A = b; 
b = tmp; 
  ///Traditional division operation int Partition (int a[], int low, int high) {int pivot = A[low]; 
  int i = low; 
      for (int j=low+1; j<=high; ++j) {if (a[j) <= pivot) {++i; 
    Swap (A[i], a[j]); 
  } swap (A[i], a[low]); 
return i; 
  //randomization division operation, randomly select pivot int partition_random (int a[], int low, int high) {srand (NULL); 
  int i = rand ()% (high+1); 
  Swap (A[low], a[i]); 
Return Partition (A, Low, high); }//Traditional fast-row void QuickSort (int a[], int low, int high) {if (Low < high) {int pos = Partition (A, Low, hig 
    h); QuiCksort (A, Low, pos-1); 
  QuickSort (A, pos+1, High); }///randomization quick sort void quicksort_random (int a[], int low, int high) {if (Low < high) {int pos = Partitio 
    N_random (A, Low, high); 
    Quicksort_random (A, Low, pos-1); 
  Quicksort_random (A, pos+1, High); 
  int main () {clock_t T1, T2; 
  Initialize array int a[30000]; 
     
  for (int i=0; i<30000; ++i) a[i] = i+1; 
  T1 = Clock (); 
  QuickSort (A, 0, 30000-1); 
  T1 = Clock ()-T1; cout << "Traditional quicksort took" << T1 << "clicks (about) << ((float) t1)/clocks_per_sec <& Lt 
 
  "seconds)." << Endl; 
  t2 = Clock (); 
  Quicksort_random (A, 0, 30000-1); 
  t2 = Clock ()-T2; cout << "Randomized quicksort took" << T2 << "clicks (about) << ((float) T2)/clocks_per_sec &LT;&L T 
 
  "seconds)." << Endl; 
return 0;
 }

The results of the operation are as follows:

[Songlee@localhost ~]$./quicksort  
Traditional QuickSort took 1210309 (about clicks 1.21031). 
Randomized quicksort took 457573 clicks (about 0.457573 seconds). 
[Songlee@localhost ~]$./quicksort  
Traditional QuickSort took 1208038 (about clicks 1.20804). 

From the results of the operation can be seen, for the orderly input, the random version of the rapid sorting efficiency is much higher.

Problem Record:

We know that the value of swapping two variables has the following three ways:

int tmp = A; Method a 
= b; 
b = tmp 
 
a = a+b;//Method two 
B = a-b; 
A = A-b; 
 
A = A^b; Method three 
B = a^b; 
A = A^b;

But you will find that in this program, if the SWAP function uses the following two methods, there will be an error. Since method two and method three do not use intermediate variables, the principle of exchanging values is to operate directly on the memory unit of the variable. If two variables correspond to the same memory unit, then after two times of addition or subtraction or operation, the value of the memory unit has changed to 0, so the variable value exchange cannot be realized. So when you need to exchange the value of the variable may be the same variable, you must use the third variable to implement the Exchange, otherwise the variable will be zero.

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.