一、归并排序
归并排序+求逆序对:(hdu4911)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=100005; 4 typedef long long ll; 5 ll a[maxn], b[maxn], cnt;//cnt用于记录逆序对的数目 6 ll n, k; 7 void merge(ll l, ll mid, ll r){ 8 ll i=l, j=mid+1, t=0; 9 while(i<=mid && j<=r){ 10 if(a[i]>a[j]){ 11 b[t++]=a[j++]; 12 cnt+=mid-i+1; //记录逆序对的数量 13 } 14 else b[t++]=a[i++]; 15 } 16 //一个子序列中的数都处理完了,另一个还没有,把剩下的直接复制过去 17 while(i<=mid)b[t++]=a[i++]; 18 while(j<=r)b[t++]=a[j++]; 19 for(int i=0; i<t; i++)a[l+i]=b[i];//把排好序的b[]复制回a[] 20 } 21 void mergesort(ll l, ll r){ 22 if(l<r){ 23 ll mid=(l+r)/2; //平均分成两个子序列 24 mergesort(l, mid); // 25 mergesort(mid+1, r); // 26 merge(l, mid, r); //合并子序列 27 } 28 } 29 int main() 30 { 31 32 cin>>n; 33 for(int i=1; i<=n; i++)cin>>a[i]; 34 mergesort(1, n); 35 cout<<cnt; 36 return 0; 37 }
二、快速排序
1.写法一:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1000010; 4 int n, a[maxn]; 5 void qsort(int l, int r){ 6 int i=l, j=r, mid=a[(i+j)/2]; 7 do{ 8 while(a[i]<mid)i++; 9 while(a[j]>mid)j--; 10 if(i<=j){ 11 swap(a[i], a[j]); 12 i++; j--; 13 } 14 }while(i<=j); 15 16 for(int k=1; k<=n; k++)cout<<a[k]<<" "; 17 cout<<endl; 18 19 if(l<j)qsort(l, j); 20 if(i<r)qsort(i, r); 21 } 22 int main() 23 { 24 cin>>n; 25 for(int i=1; i<=n; i++)cin>>a[i]; 26 qsort(1, n); 27 for(int i=1; i<=n; i++)cout<<a[i]<<" "; cout<<endl; 28 29 return 0; 30 }
2.写法二:(POJ2338)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; 4 int data[maxn]; 5 int partition(int left, int right){ //划分成左、右两部分,以i指向的数为边界 6 int i=left; 7 int temp=data[right]; //把尾部的数看成基准数 8 for(int j=left; j<right; j++){ 9 if(data[j] < temp){ 10 swap(data[j], data[i]); 11 i++; 12 } 13 } 14 swap(data[i], data[right]); 15 return i; //返回基准数的位置 16 } 17 void quicksort(int left, int right){ 18 if(left<right){ 19 int i=partition(left, right); //划分 20 quicksort(left,i-1); //分治:i左边的继续递归划分 21 quicksort(i+1,right); //分治:i右边的继续递归划分 22 } 23 } 24 int main() 25 { 26 int n; 27 cin>>n; 28 for(int i=1; i<=n; i++)cin>>data[i]; 29 quicksort(1, n); 30 for(int i=1; i<=n; i++)cout<<data[i]<<" "; cout<<endl; 31 cout<<data[(1+n)/2]; 32 return 0; 33 }
3.求前第k大的数(hud1425)(时间复杂度为O(n)) 为什么基于快排的查找第k大数时间复杂度是O(n)?
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; 4 int data[maxn]; 5 int n, k; 6 int partition(int left, int right){ 7 int i=left; 8 int temp=data[right]; 9 for(int j=left; j<right; j++){ 10 if(data[j] < temp){ 11 swap(data[j], data[i]); 12 i++; 13 } 14 } 15 swap(data[i], data[right]); 16 return i; 17 } 18 int quicksort(int left, int right){ 19 if(left<right){ 20 int i=partition(left, right); 21 if(i>k)return quicksort(left,i-1); 22 else if(i<k)return quicksort(i+1,right); 23 else return data[i]; 24 } 25 } 26 int main() 27 { 28 29 cin>>n>>k; 30 for(int i=1; i<=n; i++)cin>>data[i]; 31 32 cout<<quicksort(1,n); 33 return 0; 34 }