C language: quick sort

Quick sort is an algorithm with an average time complexity of O(n*log n) in the sorting algorithm. Its implementation needs to solve such a problem first. For a sequence A[1], A[2], A[3 ] ......A[N], adjust the position of elements in the sequence, so that all elements on the left of A[1] (the first element in the original sequence, the same below) do not exceed A[1] , all elements on the right are greater than A[1], for example, for the sequence {5,3,9,6,4,1}, it becomes {3,1,4,5,9,6} after adjustment, so that Let A[1] = 5, all elements on the left, no more than it, and all elements on the right are greater than it.

sorting ideas

1. Quicksort is an improvement to bubble sort. In quicksort, the comparison and movement of elements are carried out from both ends to the middle, and elements with larger key codes can be moved from the front to the back at one time. Smaller elements can be moved from the back to the front in one go, and elements are moved farther away, reducing the total number of comparisons and moves

2. Quick sort is designed based on the divide-and-conquer method, and its divide-and-conquer strategy is: 
1. Divide: select an element as the axis value, and divide the entire sequence into two subsequences based on the axis value. The position of the axis value is determined during the division process, and the elements of the former subsequence are all less than or equal to the axis value, and the elements of the latter subsequence are greater than or equal to the axis value

2. Solve the sub-problems: Recursively process each subsequence after division 
3. Merge: Since the sorting of the subsequences is performed in-place, the merging does not need to perform any operations

Sort method

1. Select the axis value, which is generally the key to select the first element. The worst case of a quicksort is that if the elements to be sorted are in positive or reverse order, elements other than the axis value will be divided to one side of the axis value. 
2. Divide 
①, set the division interval: i=first,j=end 
②, perform the right scan until r[j] is less than the axis value, exchange r[j] with r[i], i++ 
③, perform the left side Scan until r[i] is greater than the axis value, exchange r[i] with r[j], j– 
④, repeat two to three until i=j, determine the position of the axis value, and return to this position

 

Initial key-value sequence 23 12 35 6 19 50 28

After one division    [19 13 6] 23   [35 50 28]

Quicksort respectively [6 13] 19 [28] 35    [50]

          6  [13]             35 

             13    28        50

Final result 6 13 19 23 28 35 50

 

1  // divide the interval [left,right] 
2  int Partition( int A[], int left, int right)
 3  {
 4      int temp =A[left]; // Store in the temporary variable temp 
5  
6      while (left < right) // As long as left and right don't meet 
7      {
 8          while (left < right && A[right] > temp) right--; // Repeat left shift 
9          A[left] = A[right];
 10  
11          while (left < right && A[left] <= temp) left++; // Repeatedly move right by 
12         A[right] = A[left];
 13      }
 14  
15      A[left] = temp;     // put temp where right and left meet 
16      return left;     // return the encounter subscript 
17 }

The quick sort algorithm is efficient when the arrangement of elements in the sequence is relatively random, but when the elements in the sequence are close to order, the worst time complexity O(n^2) will be reached. The main reason for this is that the pivot element does not Divide the current interval into two subintervals of similar length. Is there any way to solve this problem? That is to choose the pivot at random, so that while the worst time complexity of the algorithm is still O(n^2) (for example, A[left] is always chosen as the pivot), the expected time complexity for any input data is It can reach O(n*log n), that is, there is no specific set of data that can make the algorithm perform the worst case.

 

 1 int randPartition(int A[],int left, int right)
 2 {
 3     //生成[left,right]内的随机主元
 4     int p = (round(1.0*rand()/RAND_MAX)*(right-left)+left);
 5     swap(A[p],A[left]);
 6     int temp =A[left];
 7     while(left < right)
 8     {
 9         while(left < right && A[right] > temp) right--;//反复左移
10         A[left] = A[right];
11         while(left < right && A[left] <= temp) left++;//反复右移
12         A[right] = A[left];
13     }
14     A[left] = temp;
15     return left;
16 }

The recursive implementation of quicksort is as follows:

 

1  // quick sort, the initial values ​​of left and right are sequence subscripts (such as 1 and n) 
2  void quicksort( int A[], int left, int right)
 3  {
 4      if (left < right) // the current interval The length exceeds 1 
5      {
 6          // divide [left,right] into 2 by A[right] 
7          int pos = randPartition(A,left,right);
 8          quicksort(A, left, pos- 1 );   // Quickly sort the left subinterval recursively 
9          quicksort(A, pos+ 1 , right); // Quickly sort the right subinterval recursively 
10      }
11 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325220911&siteId=291194637