資料結構實驗之排序五 歸併求逆序數

2021-07-17 03:15:39 字數 1526 閱讀 6287

time limit: 20ms   memory limit: 65536k  

對於數列a1,a2,a3…中的任意兩個數ai,aj (i 

< j),如果ai > aj,那麼我們就說這兩個數構成了乙個逆序對;在乙個數列中逆序對的總數稱之為逆序數,如數列 1 6 3 7 2 4 9中,(6,4)是乙個逆序對,同樣還有(3,2),(7,4),(6,2),(6,3)等等,你的任務是對給定的數列求出數列的逆序數。

輸入資料n(n <= 100000)表示數列中元素的個數,隨後輸入n個正整數,數字間以空格間隔。

輸出逆序數。

10

10 9 8 7 6 5 4 3 2 1

45

歸併(merge)排序

法是將兩個(或兩個以上)有序表合併成乙個新的有序表,即把待排序序列分為若干個子串行,每個子串行是有序的。然後再把有序子串行合併為整體有序序列。

歸併排序

是建立在歸併操作上的一種有效的排序

演算法。該演算法是採用分治法

(divide and conquer)的乙個非常典型的應用。

將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為2-路歸併。

歸併操作(merge),也叫歸併演算法,指的是將兩個已經排序的序列合併成乙個序列的操作。 如 設有數列

如:初始狀態: [6] [202] [100] [301] [38] [8] [1] 比較次數

i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3

i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4

i=3 [ 1 6 8 38 100 202 301 ] 4

歸併排序是將數列a[l,h]分成兩半a[l,mid]和a[mid+1,h]分別進行歸併排序,然後再將這兩半合併起來。

在合併的過程中(設l<=i<=mid,mid+1<=j<=h),當a[i]<=a[j]時,並不產生逆序數;當a[i]>a[j]時,在

前半部分

中比a[i]大的數都比a[j]大,將a[j]放在a[i]前面的話,逆序數要加上mid+1-i。因此,可以在歸併 排

序中的合併過程

中計算逆序數.

#include#define maxn 100000

int a[maxn],r[maxn];

int n,m;

long long sum;

void merge(int low,int mid,int high) //二路歸併演算法

}while(i<=mid)

r[k++]=a[i++];

while(j<=high)

r[k++]=a[j++];

for(i=0; ia[i+low]=r[i];

}void mergesort(int low,int high) //自頂向下的二路歸併排序

}int main()

資料結構實驗之排序五 歸併求逆序數

time limit 20ms memory limit 65536k 有疑問?點這裡 對於數列a1,a2,a3 中的任意兩個數ai,aj i j 如果ai aj,那麼我們就說這兩個數構成了乙個逆序對 在乙個數列中逆序對的總數稱之為逆序數,如數列 1 6 3 7 2 4 9中,6,4 是乙個逆序對,...

資料結構實驗之排序五 歸併求逆序數

time limit 20ms memory limit 65536k 對於數列a1,a2,a3 中的任意兩個數ai,aj i j 如果ai aj,那麼我們就說這兩個數構成了乙個逆序對 在乙個數列中逆序對的總數稱之為逆序數,如數列 1 6 3 7 2 4 9中,6,4 是乙個逆序對,同樣還有 3,2...

資料結構實驗之排序五 歸併求逆序數

time limit 20ms memory limit 65536k 有疑問?點這裡 對於數列a1,a2,a3 中的任意兩個數ai,aj i j 如果ai aj,那麼我們就說這兩個數構成了乙個逆序對 在乙個數列中逆序對的總數稱之為逆序數,如數列 1 6 3 7 2 4 9中,6,4 是乙個逆序對,...