归并排序

来源:互联网 发布:音乐视频制作软件 编辑:程序博客网 时间:2024/06/08 05:34

归并排序算法可以递归地描述为:算法将数组分为两半,对每部分递归地应用归并排序。

下图演示了对由8个元素(2 9 5 4 8 1 6 7)构成的数组进行的归并排序。原始数组分为

(2 9 5 4)和(8 1 6 7)两个数组。对这两个子数组递归的应用归并排序,将(2,5,9,4)

分为(2,5)和(9,4),并将(8,1,6,7)分为(8,1)和(6,7)。继续进行这个过程直到子数组

只包含一个元素为止。例如,将数组(2,9)分为(2)和(9)。由于(2)包含的是单一元素,

所以不能再细分。现在,将(2)和(9)归并为一个新的有序数组(2,9);同理,将(5),(4)

归并成(4,5)。然后将(2,9)和(4,5)归并成(2,4,5,9)…………以此类推

OJ练习题目地址:求逆序数http://acm.nyist.net/JudgeOnline/problem.php?pid=117

AC CODE:

 #include <stdio.h>#include <stdlib.h>int a[1000005];long long ans;void merge(int start,int mid,int end)   //归并{int i = start,j = mid + 1,k = 0;int *temp = (int *)malloc((end-start+1)*sizeof(int));while(i <= mid && j <= end)        //合并{if(a[i] <= a[j])temp[k++] = a[i++];else{temp[k++] = a[j++];ans += (mid - i +1);}}while(i <= mid)         //剩余的元素归并temp[k++] = a[i++];while(j <= end)temp[k++] = a[j++];for( i = start; i <= end; i++ )a[i] = temp[i - start];free(temp);}void merge_soft(int start,int end)     //排序{int mid;if(start < end){mid = (start + end) / 2;   //递归,直到剩一个元素为止merge_soft(start,mid);merge_soft(mid+1,end);merge(start,mid,end);}}int main(){int t,n,i;scanf("%d",&t);while(t--){ans = 0;scanf("%d",&n);for( i = 0; i < n; i++ )scanf("%d",&a[i]);merge_soft(0,n-1);printf("%lld\n",ans);}return 0;}        


 

原创粉丝点击