1. 程式人生 > 實用技巧 >歸併和快排

歸併和快排

一、歸併排序

歸併排序+求逆序對:(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  }