nyoj 322 117 求逆序数 归并排序
来源:互联网 发布:匡恩网络招聘 编辑:程序博客网 时间:2024/06/05 20:12
此题相当于问冒泡从小大大排序中交换了多少次,但是冒泡的时间复杂度的n^2,所以不可取,可以换用归并排序,归并排序时间复杂度为nlogn,还行,之前只听过归并排序的概念(毕竟有sort),没有敲过代码,这次参考别人的博客水一发,
比如现在有两组已经从小到大排好的数据 5 10 15 17和3 9 11 12 30
要将这两组数据整合到一起,同时按从小到大排序
那么可以先比较两组数据的第一个数字 5 和3,3小,取3,同时去掉3,再比较5 和9,取5同时去掉5,再比较10和9,9小取9同时去掉,以此类推,得到3 5 9 10 11 12 15 17 30 如果现在有一组数据要排大小的话,我们就可以将这一组数据分成两组,同时这两组的每一组再分成两组,直到每组数据为两个数(也可能为1个数),然后比较排序,这样就得到了已经排好序的数据,再两两比较类似于上面的例子,重新整合到一块。
概念容易理解,但是代码不是很好理解:
#include<stdio.h>int a[1000010],b[1000010];long long s=0;void sort(int first,int mid,int last){ int i=first,k=first,j=mid+1; while(i<=mid&&j<=last) //先将左一半或右一半的数据取完, { if(a[i]<=a[j]) b[k++]=a[i++]; else s+=j-k,b[k++]=a[j++]; //s+=j-k是关键,想想为什么,^_^ } while(i<=mid) //剩下的数据均是大的,所以取完 因为不知道到底是左一半先取完还是右一半先取完,所以两者都尝试 b[k++]=a[i++]; while(j<=last)//剩下的数据均是大的,所以取完 b[k++]=a[j++]; for(i=first; i<=last; i++) //再重新将b[]赋值给a[] a[i]=b[i];}void msort(int first,int last){ int mid=(first+last)/2; if(first<last) //一直递归直到first==last msort(first,mid),msort(mid+1,last),sort(first,mid,last); //先把左一半和右一半排序,然后再整合}int main(){ int nn; scanf("%d",&nn); while(nn--) { int n,i; scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d",&a[i]); s=0; msort(1,n); printf("%lld\n",s); }}
1 0
- NYOJ 117 求逆序数【归并排序求逆序数】
- 归并排序求逆序数 NYOJ 117
- nyoj 322 117 求逆序数 归并排序
- NYOJ - 求逆序数(归并排序)
- nyoj 求逆序数(归并排序)
- NYOJ 322 Sort(归并排序求逆序数)
- NYOJ 117 求逆序数 【树状数组】或【归并排序】
- NYOJ-117 求逆序数(树状数组或归并排序)
- nyoj-117(归并排序求逆序数)
- ACM--归并排序&&树状数组--nyoj 117--求逆序数
- NYOJ 117 求逆序数 (归并排序)
- nyoj 117 求逆序数 (归并排序)
- nyoj 117 归并求逆序数
- nyoj 117 求逆序数 【归并排序&&逆序数反转次数】
- nyoj 117 求逆序数【归并求逆序】
- 归并排序,求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- Jquery ajax 跨域访问
- 编程小练习
- android4.2系统增永不休眠同时隐藏休眠选项
- cisco learn book index 2
- 项目管理经验总结
- nyoj 322 117 求逆序数 归并排序
- 自定义tableview分割线
- LeetCode 142. Linked List Cycle II
- 电池企业管理软件
- PSI信息解析
- md5码加密
- HTTP发送POST请求说明
- 【Bugly干货分享】手把手教你逆向分析 Android 程序
- Android之Adapter用法总结