Data Structure Algorithm Learning Summary - MOOC (9) Quick Sort (from small to large)
1. Review
The previous section is down to bottom-up merge sort
This section will talk about a high-performance sort, quicksort
2. Analysis
The idea of quick sort is to first take the first element of the array, denoted it as v, and find a suitable position p, satisfying that the elements before the p position are all less than v, and the elements after p are greater than or equal to v, and then for less than v and Elements greater than or equal to v are then sorted recursively
For the array {4,5,1,3}, 4 is recorded as v, compare 5 and 4, 5 is larger than 4, and continue to the next element 1; 1 and 4 are compared and found that 1 is smaller than 4, then swap 5 and 1 position, now the array becomes {4,1,5,3}; compare 3 and 4, find that 3 is smaller than 4, swap the positions of 5 and 3, now the array becomes {4,1,3,5}, finally swap At the positions of 3 and 4, the array becomes {3,1,4,5}, the elements before 4 are less than 4, the elements after 4 are greater than or equal to 4, and then 3,1 can be sorted
3. Actual combat
QuickSort.h
#ifndef QUICKSORT_H_ #define QUICKSORT_H_ #include <iostream> using namespace std; /** * Partition operation on the [l...r] part * Return p such that arr[l...p-1]<arr[p],arr[p+1,r]>=arr[p] */ template<typename T> int __partition(T arr[],int l,int r){ T v = arr[l]; //arr[l+1...j] < v ,arr[j+1...i] >= v int j = l; for(int i = l+1;i<=r;i++){ if(arr[i] < v){ swap(arr[j+1],arr[i]); j++; } } swap(arr[l],arr[j]); return j; } /** * Quick sort the arr[l...r] part */ template<typename T> void __quickSort(T arr[],int l,int r){ if(l >= r) return; int p = __partition(arr,l,r); __quickSort(arr,l,p-1); __quickSort(arr,p+1,r); } template<typename T> void quickSort(T arr[],int n){ __quickSort(arr,0,n-1); } #endif /* QUICKSORT_H_ */
4. Think
For an array that is nearly ordered or has many duplicate key values, such a quick sort is actually very inefficient. Although the theoretical time complexity is nlogn level, the time complexity at this time may degenerate to the worst n^ Level 2
5. Optimization
For nearly ordered arrays
#ifndef QUICKSORT_H_ #define QUICKSORT_H_ #include <iostream> #include "InsertSort.h" using namespace std; /** * Partition operation on the [l...r] part * Return p such that arr[l...p-1]<arr[p],arr[p+1,r]>=arr[p] */ template<typename T> int __partition(T arr[],int l,int r){ swap(arr[l],arr[rand()%(r - l +1)+l]); T v = arr[l]; //arr[l+1...j] < v ,arr[j+1...i] >= v int j = l; for(int i = l+1;i<=r;i++){ if(arr[i] < v){ swap(arr[j+1],arr[i]); j++; } } swap(arr[l],arr[j]); return j; } /** * Quick sort the arr[l...r] part */ template<typename T> void __quickSort(T arr[],int l,int r){ // if(l >= r) // return; if(r - l<= 15){ insertSort(arr,l,r); return; } int p = __partition(arr,l,r); __quickSort(arr,l,p-1); __quickSort(arr,p+1,r); } template<typename T> void quickSort(T arr[],int n){ __quickSort(arr,0,n-1); srand(time(NULL)); } #endif /* QUICKSORT_H_ */
For arrays with many duplicate key values
Others remain unchanged, modify the partition
/** * Optimized partition to avoid extreme imbalance due to many duplicate key values */ template<typename T> int __partition2(T arr[],int l,int r){ swap(arr[l],arr[rand()%(r - l +1)+l]); T v = arr[l]; //arr[l+1...i)<=v,arr[j...r]>=v int i = l+1,j = r; while(true){ while(i<=r && arr[i] < v) i++; while(j>=l+1 && arr[j] > v) j--; if(i > j) break; swap(arr[i],arr[j]); i++; j--; } swap(arr[l],arr[j]); return j; }
6. Opinions and Suggestions
If you have any questions or suggestions, please leave a message to discuss