歸併排序和逆序對數量
阿新 • • 發佈:2021-11-05
歸併排序
#include<iostream> using namespace std; const int N = 100010; int q[N]; int tmp[N]; void merge_sort(int q[],int l, int r) { if(l >= r) return ; int mid = l + r >> 1; merge_sort(q, l, mid); merge_sort(q, mid + 1, r); int k = 0, i = l ,j = mid + 1; while(i <=mid && j<= r) if(q[i] <= q[j]) tmp[k++] = q[i++]; else tmp[k++] = q[j++]; while(i <= mid) tmp[k++] = q[i++]; while(j <= r) tmp[k++] = q[j++]; for(i = l,j = 0;i <= r;i++, j++) q[i] = tmp[j]; } int main() { int n; scanf("%d",&n); for (int i = 0; i < n; i ++ ) { scanf("%d",&q[i]); } merge_sort(q, 0, n - 1); for (int i = 0; i < n; i ++ ) { printf("%d ",q[i]); } }
1.先找中間的點,與快排不一樣的是,他要求是位置在中間
2.分成左右兩邊,歸併處理左右兩邊
3.歸併排序,將左右兩個有序序列合併成一個有序的序列
逆序對數量
#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int N = 100010; int q[N], tmp[N]; LL merge_sort(int q[],int l, int r){ if(l >= r) return 0; int mid = r + l >> 1; LL res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r); int k = 0, i = l, j = mid + 1; while(i <= mid && j <= r) { if(q[i] <= q[j]) tmp[k++] = q[i++]; else { res += mid - i + 1; tmp[k++] = q[j++]; } } while(i <= mid) tmp[k++] = q[i++]; while(j <= r) tmp[k++] = q[j++]; for(i = l, j = 0; i <= r;i++, j++) q[i] = tmp[j]; return res; } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i ++ ) { scanf("%d", &q[i]); } cout << merge_sort(q, 0, n - 1); return 0; }
會產生逆序對只會在mid的左右兩邊時,此時若i的值大於j的值,那麼i後面的數的值必然會大於j的值。