高效算法设计_再谈排序和检索(归并排序,逆序数对)
来源:互联网 发布:阶乘递归算法 编辑:程序博客网 时间:2024/06/07 16:31
归并排序
上一个分治法的扩展
划分:把序列分成元素个数尽量相等的两半。
递归求解:把两半的元素分别排序
合并:把两个有序表合并成一个
输入:
81 2 12 11 9 7 13 20
输出:
1 2 7 9 11 12 13 20
#include <stdio.h>#define MAXSIZE 1024void merge_sort(int *A,int x,int y,int *T){ //T是辅助空间 int i; if(y-x>1){ //递归入口,所剩元素大于1,只有一个元素没有必要排序 int m=x+(y-x)/2;//分治第一步,划分,技巧,向中间靠拢 int p=x,q=m,i=x; merge_sort(A,x,m,T);//分治第二步,递归求解。 merge_sort(A,m,y,T); while(p<m||q<y){//只要有一个序列非空,就要继续合并 if(q>=y||(p<m&&A[p]<=A[q])) //第二个序列为空,或者两个序列都不为空,比较小的赋值,赋值A[p]. T[i++]=A[p++]; else T[i++]=A[q++]; //否则第二个不为空,且第一个为空,或者,两个都不为空,且A[p]<=A[q]时,才赋值A[q] } for(i=x;i<y;i++) A[i]=T[i]; //右边的y是取不到的 }}void print(int* A,int n)//比赛中避免最后一个空格检查出错误。{ for(int i = 0 ; i < n; i++) { if(i) { printf(" %d",A[i]); } else { printf("%d",A[i]); } } printf("\n");}void process()//输入程序。{ int n; while(scanf("%d",&n)!=EOF) { int A[MAXSIZE]; int T[MAXSIZE]; for(int i = 0 ; i < n ; i++) { scanf("%d",&A[i]); } merge_sort(A,0,n,T); print(A,n); }}int main(int argc,char* argv[]){ process(); return 0;}
逆序对数
题目: 给一列数a1,a2,a3,…,an。求它的逆序对数,即有多少个有序对(i,j),使得i
输入:
8 1 9 6 3 4 7 9 0
输出:
0 1 2 3 3 4 6 6 10 12 13 13 0 1 3 4 6 7 9 913
第一行为计数过程表示cout逐渐自加的过程.
计算步骤:
刚开始归并排序两两分组 (1,9)(6,3)||(4,7)(9,0)
后面一位和前面一位进行对比,如果 i<j 且 ai>aj,逆序数对就加1
对于前半部分 count=0+1; 重排合并后(1,9,3,6) count=0+1+1+1.
对于后半部分count=3+0+1;重排合并后(4,7,0,9)count=3+0+1+2+0;
然后再重排合并(1,3,6,9,0,4,7,9)count=6+4+2+1+0=13,及最终结果
#include <stdio.h>#define MAXSIZE 1024int count,k=0;int K[MAXSIZE];void mergeSort(int* A,int x,int y,int* T){ if(y-x>1) { int m = x + (y - x) / 2 ; int p=x,q=m,i=x; mergeSort(A,x,m,T); mergeSort(A,m,y,T); while(p < m || q < y) { //if(m >= high || (l < mid && iArr[l] < iArr[m])) if(q>= y||(p < m && A[p] <= A[q]))//=与号不能漏 { T[i++] = A[p++]; } else { T[i++]=A[q++]; count+=m-p; printf("%d ",count); } } for(int j = x ; j < y ; j++) { A[j]=T[j]; } }}void print(int* A,int n){ for(int i = 0 ; i < n; i++) { if(i) { printf(" %d",A[i]); } else { printf("%d",A[i]); } } printf("\n");}void process(){ int n; while(scanf("%d",&n)!=EOF) { count = 0; int A[MAXSIZE]; int T[MAXSIZE]; for(int i=0;i<n;i++) { scanf("%d",&A[i]); } mergeSort(A,0,n,T); print(A,n); printf("%d\n",count); }}int main(){ process(); getchar(); return 0;}
阅读全文
0 0
- 高效算法设计_再谈排序和检索(归并排序,逆序数对)
- 归并排序和求逆序数对
- 【算法】归并排序(可求逆序数或逆序对)
- 归并排序和逆序数
- 归并排序和逆序对
- 归并排序(求逆序数对)
- 归并排序--逆序数对的计算
- 数据结构 归并排序-逆序数对
- 求逆序数对(归并排序)
- 利用归并排序求逆序数对
- Inversion(HDU_4911) 归并排序+逆序数对
- 利用归并排序求逆序数对
- 归并排序,逆序数
- 归并排序 逆序数
- 归并排序+逆序数
- 归并排序 + 逆序数
- 算法导论 归并排序解决逆序数
- 归并排序-求逆序数算法
- gradle 创建spring boot项目
- HDU6106 Classes(思路,2017 HDU多校联赛 第6场)
- 区间dp模型
- UVA
- 程序员必背单词1
- 高效算法设计_再谈排序和检索(归并排序,逆序数对)
- spring面试题
- 关于项目自动化工具的知识(ant,maven,gradle)
- HDOJ1978 How many ways 记忆化搜索入门题
- 有用的函数--功能:求平方根倒数
- hdu 3371 Connect the Cities
- C++ Windows Server 2008 以上版本中IIS安装FastCGI组件
- Java数据结构与算法
- hdu 6097 Mindis (高中数学)