归并和快排

一、归并排序

归并排序+求逆序对:(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  } 
View Code

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  } 
原文地址:https://www.cnblogs.com/tflsnoi/p/13544765.html