快速排序
在待排序元素中选择一个“主元“,小于主元的排在前,大于主元的排在后。
1.普通快速排序:
//交换x和y的值 void swap(int &x, int &y) { int temp=x; x = y; y = temp; } //a为数列,起点start,终点end(end为排序数组最后一位数的下标) void FastSort(int *a, int start, int end) { if (start >= end) { return; } //Patition操作:将key放到合适的位置,使得其左边的数都不大于它,右边的数都不小于它 int key = a[start]; int j = start; for (int i = start + 1; i <= end; i++) { if (a[i] < key) { //当a[i]<key时,交换a[++j]和a[i] swap(a[++j],a[i]); } } swap(a[start], a[j]); //对key两边的数继续进行排序 FastSort(a,start, j - 1); FastSort(a,j + 1, end); }
2.二路快排
和快排不同的是此时我们将小于主元和大于主元的元素放在数组的两端
#include<iostream> #include<algorithm> using namespace std; template <typename T> int partition(T arr[],int l,int r) { T v=arr[l]; int i,j; i=l+1;j=r; while(true) { while(arr[i]<v&&i<=r)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; } template <typename T> void __quicksort2(T arr[],int l,int r) { if(l>=r) return ; int p=partition(arr,l,r); __quicksort2(arr,l,p-1); __quicksort2(arr,p+1,r); } template <typename T> void quicksort(T arr[],int n) { __quicksort2(arr,0,n-1); } int main() { int arr[100],n; cin>>n; for(int i=0;i<n;i++) cin>>arr[i]; quicksort(arr,n); for(int i=0;i<n;i++) cout<<arr[i]<<" "; cout<<endl; return 0; }
3.三路快排
双路快排将整个数组分成了小于主元,大于主元的两部分,而三路快排则是将数组分成了小于主元,等于主元,大于主元的三个部分,当递归处理的时候,遇到等于v的元素直接不用管,只需要处理小于主元,大于主元的元素就好了。
#include<iostream> #include<algorithm> using namespace std; template <typename T> void __quicksort3(T arr[],int l,int r) { if(l>=r) return ; T v=arr[l]; int lt=l; int gt=r+1; int i=l+1; while(i<gt) { if(arr[i]<v) {swap(arr[i],arr[lt+1]); lt++; i++;} else if(arr[i]>v) { swap(arr[i],arr[gt-1]); gt--; } else { i++; } } swap(arr[l],arr[lt]); __quicksort3(arr,l,lt-1); __quicksort3(arr,gt,r); } template <typename T> void quicksort3(T arr[],int n) { __quicksort3(arr,0,n-1); } int main() { int a[100],n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; quicksort3(a,n); for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; return 0; }