1. 程式人生 > 其它 >逆序數的實現——基於二路歸併排序

逆序數的實現——基於二路歸併排序

逆序數的判定

可利用二路歸併排序的基本思想:

法一:左邊有序陣列和右邊有序陣列比對,如果左邊的下標為i的值>右邊下標為j的值,則表示i及其後面(直到middle)的所有值都大於右邊下標為j的值

法二:或者說左邊下標為i的值大於右邊下標為j及其左邊(直到middle+1)的所有值()但這個就需要在後面多些程式碼,下面會詳細說。

法一:

/*
-------------------------------------------------
   Author:       wry
   date:         2022/3/1 17:10
   Description:  test
-------------------------------------------------
*/ #include <bits/stdc++.h> using namespace std; const int MAXN = 1000+10; int arr[MAXN]; int temp[MAXN]; int number; void Combine(int left,int middle,int right) { int i = left; int j = middle+1; int k = left; while (i<=middle && j<=right) { if (arr[i]<=arr[j]) { temp[k]
= arr[i]; i++; k++; } else if (arr[i]>arr[j]){ //表示i及其之後的位置都大於j,相當於逆序對的(a,b)的b已經判斷ok temp[k] = arr[j]; j++; k++; number += middle-i+1; } } while (i<=middle) { //說明剩下的都是更大的,但是b已經全部判斷完,所以不用再額外新增
temp[k] = arr[i]; i++; k++; } while (j<=right) { temp[k] = arr[j]; j++; k++; } for (int t=left;t<=right;t++) { arr[t] = temp[t]; } } void MergeSort(int left,int right) { if (left < right) { int middle = left+(right-left)/2; MergeSort(left,middle); MergeSort(middle+1,right); Combine(left,middle,right); } else { return ; } } int main() { int n; while (cin>>n) { number = 0; for (int i=0;i<n;i++) { cin >> arr[i]; } MergeSort(0,n-1); for (int i=0;i<n;i++) { cout << arr[i] << " "; } cout << endl << number << endl; } return 0; }

法二需要改的地方為:

while (i<=middle && j<=right) {
  if (arr[i]<=arr[j]) {
    temp[k] = arr[i];
    i++;
    k++;
  }
  else if (arr[i]>arr[j]){   
    temp[k] = arr[j];
    j++;
    k++;
    number += j-middle+1;    //這裡
  }
}
while (i<=middle) {     
  temp[k] = arr[i];
  i++;
  k++;
  number++;        //這裡
}
while (j<=right) {
  temp[k] = arr[j];
  j++;
  k++;
}