归并排序
Posted johnfllora
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序相关的知识,希望对你有一定的参考价值。
归并排序
个人认为归并排序和快速排序有相似之处,都是从大数组一步一步化为小数组再分步解决。
归并排序的思想其实很简单,总共分为两步,分与治。
分指的就是将一个大数组一步一步变小,总体化小再化小,如下图本是长度为8的数组分为两个长度为4的数组再一步一步分下去直到8个数字。
核心代码
int mid=(start+end)/2;
7 if(start<end)
8 {
9 memerge(s,start,mid);
10 memerge(s,mid+1,end);
11 }
治就是将小的数组排好序,再一步步整合为大的数组。
之所以要先不断分,是为了左右两侧每次分的小数组要保证有序,才可以进行归并操作。
核心代码
for(i=start,j=1,k=0;i<=mid&&mid+j<=end;)
15 {
16 if(s[i]>s[mid+j])
17 {
18 ans+=(mid-i+1);
19 n[k++]=s[mid+j++];
20 }
21 else
22 {
23 n[k++]=s[i++];
24 }
25 }
26 while(i<=mid)n[k++]=s[i++];
27 while(mid+j<=end)n[k++]=s[mid+j++];
28 for(i=start,k=0;k<end-start+1;k++)
29 s[i+k]=n[k];
30 }
-
归并排序的时间复杂度为O(nlogn) ,因为递归(分)每次按照一半分区(八个变四个)。最重要的是该算法中最好、最坏和平均的时间性能都是O(nlogn)。
快速排序虽然时间复杂度为O(nlogn)但是有特殊情况。 相比较就是因为归并排序使用空间换时间。
完整代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 long long int ans=0; 4 void memerge(long long int *s, int start, int end) 5 { 6 int mid=(start+end)/2; 7 if(start<end) 8 { 9 memerge(s,start,mid); 10 memerge(s,mid+1,end); 11 } 12 int n[65599]; 13 int i,j,k; 14 for(i=start,j=1,k=0;i<=mid&&mid+j<=end;) 15 { 16 if(s[i]>s[mid+j]) 17 { 18 ans+=(mid-i+1); 19 n[k++]=s[mid+j++]; 20 } 21 else 22 { 23 n[k++]=s[i++]; 24 } 25 } 26 while(i<=mid)n[k++]=s[i++]; 27 while(mid+j<=end)n[k++]=s[mid+j++]; 28 for(i=start,k=0;k<end-start+1;k++) 29 s[i+k]=n[k]; 30 } 31 32 int main() 33 { 34 int n,i,j; 35 long long int *s; 36 scanf("%d",&n); 37 s=(long long int *)malloc(sizeof(long long int)*n); 38 for(i=0;i<n;i++) 39 { 40 scanf("%lld",s+i); 41 } 42 memerge(s,0,n-1); 43 printf("%lld ",ans); 44 ans=0; 45 }
归并排序还可以用在求逆序数中的题目,而快速排序则8太行。
以上是关于归并排序的主要内容,如果未能解决你的问题,请参考以下文章