归并排序poj2299

 

Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 19252   Accepted: 6828

Description

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
9 1 0 5 4 ,
Ultra-QuickSort produces the output 
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0
1.问题分析
应用归并排序方法。

归并排序nlog(n)的排序速度很不错,而求在排序的过程中,有个归并过程merge(),

这里是将两个有序数列归并为一个有序数列,在归并的过程中,很容易就能够计算逆序对个数,所以可以很快解决这个问题。

即:对于数列[l, mid] [mid + 1, r]的合并,i 从l开始循环,j从mid + 1开始循环,如果遇到a[i] > a[j] 则出现逆序,可以将a[j]放入辅助数组,同时j++,那么和a[j]逆序的数就有mid-i+1个,因为序列是有序的[i, mid]的所有的数都是大于a[j]的。


2.应用到的算法

比较冒泡排序和归并排序:

//-----冒泡排序----- void bubble_sort(int a[],int n) { for(i=n-1,change=TRUE;i>=1&&change;--i) { change=FALSE; for(j=0;j<i;++j) { if(a[j]>a[j+1]) { a[j]<-->a[j+1];change = TRUE; } } } }

T(n)=O(n^2)

//----------归并排序--------- MERGE-SORT(A, p, r) 1 if p < r 2 then q ← ⌊(p + r)/2⌋ 3 MERGE-SORT(A, p, q) 4 MERGE-SORT(A, q + 1, r) 5 MERGE(A, p, q, r) MERGE(A, p, q, r) 1 n1 ← q - p + 1 2 n2 ← r - q 3 create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1] 4 for i ← 1 to n1 5 do L[i] ← A[p + i - 1] 6 for j ← 1 to n2 7 do R[j] ← A[q + j] 8 L[n1 + 1] ← ∞ 9 R[n2 + 1] ← ∞ 10 i ← 1 11 j ← 1 12 for k ← p to r 13 do if L[i] ≤ R[j] 14 then A[k] ← L[i] 15 i ← i + 1 16 else A[k] ← R[j] 17 j ← j + 1

T(n)=O(nlog(n))


3.代码:

#include <stdio.h> #include <malloc.h> int L[500001]; int R[500001]; int a[500001]; long long num=0; void merge(int a[],int p,int q,int r) { int i,j,k; int n1=q-p+1; int n2=r-q; for(i=1;i<=n1;i++) { L[i]=a[p+i-1]; } for(j=1;j<=n2;j++) { R[j]=a[q+j]; } L[n1+1]=0x7fffffff; R[n2+1]=0x7fffffff; i=1;j=1; for(k=p;k<=r;k++) { if(L[i]<=R[j]) { a[k]=L[i]; i++; } else { a[k]=R[j]; j++; num+=n1-i+1; } } } void merge_sort(int a[],int p,int r) { int q; if(p<r) { q=(p+r)/2; merge_sort(a,p,q); merge_sort(a,q+1,r); merge(a,p,q,r); } } int main() { int n,i; while(scanf("%d",&n)&&n!=0) { num=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); } merge_sort(a,0,n-1); printf("%lld/n",num); } return 0; }



4.遇到的问题及解决

(1)为什么num要用long long型申请?

假设n=500000个数刚好是从大到小的一个完全逆序,则num=(500000+1)*500000/2这个数的范围超出了long 所能表示的范围

其实也可以申请为_int64

(2)main()中merge_sort函数的参数传递要正确

 


 

你可能感兴趣的:(Integer,Arrays,input,merge,n2,sorting)