2020-8-16

原地归并代码

private void merge(Comparable[] a,int lo,int mid,int hi){for(int i=lo;i<=hi;i++){tep[i]=a[i];//辅助数组tep}int left=lo;//左部分开始int right=mid+1;//右部分开始元素下标for(int i=lo;i<=hi;i++){if(left>mid) a[i]=tep[right++];//左部分用完else if(right>hi) a[i]=tep[left++];//右部分用完else if(less(tep[left],tep[right])) a[i]=tep[right++];//比较大小else a[i]=tep[left++];//比较大小}
}

自顶向下:

package Algorithm;public class Merge {private boolean less(Comparable v,Comparable w){return v.compareTo(w)>0;}Comparable[] tep;public void sort(Comparable[] a){tep=new Comparable[a.length];sort(a,0,a.length-1);}private void sort(Comparable[] a,int lo,int hi){if(hi<=lo) return;int mid=lo+(hi-lo)/2;sort(a,lo,mid);sort(a,mid+1,hi);merge(a,lo,mid,hi);}private void merge(Comparable[] a,int lo,int mid,int hi){for(int i=lo;i<=hi;i++){tep[i]=a[i];//辅助数组tep}int left=lo;//左部分开始int right=mid+1;//右部分开始元素下标for(int i=lo;i<=hi;i++){if(left>mid) a[i]=tep[right++];//左部分用完else if(right>hi) a[i]=tep[left++];//右部分用完else if(less(tep[left],tep[right])) a[i]=tep[right++];//比较大小else a[i]=tep[left++];//比较大小}}
}


自底向上:

可用于链表排序

  public void sort(Comparable[] a){tep=new Comparable[a.length];int n=a.length;for (int sz= 1; sz<n; sz=sz+sz) {//sz,数组大小(从0计算,o-5,则sz=5)for (int lo=0;lo<n-sz;lo+=sz+sz){//lo,数组开始下标。每次lo=lo+sz+sz,合并两个数组大小merge(a,lo,lo+sz-1,Math.min(n-1,lo+sz+sz-1));}}}

三种优化

1.小规模数组采用插入排序

private void sort(Comparable[] a,int lo,int hi){if(hi<=lo) return;if(hi-lo<=7){//小规模采用插入排序**********for(int i=lo;i<=hi;i++){for(int j=i;j>lo;j--){if(a[j].compareTo(a[j-1]<0)){Comparable t=a[j];a[j]=a[j-1];a[j-1]=t;}}}}int mid=lo+(hi-lo)/2;sort(a,lo,mid);sort(a,mid+1,hi);merge(a,lo,mid,hi);}

2.合并时判断是否有序

private void sort(Comparable[] a,int lo,int hi){if(hi<=lo) return;int mid=lo+(hi-lo)/2;sort(a,lo,mid);sort(a,mid+1,hi);****if(a[mid].compareTo(a[mid+1])<=0) return;*****//判断是否有序merge(a,lo,mid,hi);}

3.优化辅助数组时的时间

注意空间不能优化
将此辅助数组变为在递归中的参数即可。这样的话,上面两个代码都要改变。

package Algorithm;public class Merge {private boolean less(Comparable v,Comparable w){return v.compareTo(w)>0;}private void exch(Comparable[] a,int i,int j){Comparable t=a[i];a[i]=a[j];a[j]=t;}public void sort(Comparable[] a){Comparable[] tep=a.clone();sort(tep,a,0,a.length-1);}private void sort(Comparable[] src, Comparable[] dst, int lo, int hi){if(hi<=lo) return;if(hi<=lo+7){for(int i=lo;i<=hi;i++){for(int j=i;j>lo;j--){if(less(dst[j-1],dst[j])){exch(dst,j,j-1);}}}return;}int mid=lo+(hi-lo)/2;sort(dst,src,lo,mid);sort(dst,src,mid+1,hi);if(less(src[mid+1],src[mid])){System.arraycopy(src,lo,dst,lo,hi-lo+1);return;}merge(src,dst,lo,mid,hi);}private void merge(Comparable[] src,Comparable[] dst,int lo,int mid,int hi){int left=lo;//左部分开始int right=mid+1;//右部分开始元素下标for(int i=lo;i<=hi;i++){if(left>mid) dst[i]=src[right++];//左部分用完else if(right>hi) dst[i]=src[left++];//右部分用完else if(less(src[left],src[right])) dst[i]=src[right++];//比较大小else dst[i]=src[left++];//比较大小}}
}

参考自:https://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/MergeX.java


2019-4-23
分解:将待排序的n个元素分成n/2两个子序列
解决:使用归并排序递归的排序两个子序列
合并:合并两个已排序好的子序列来生成排序好的答案。
当待排序的序列长度为1时,递归回升,因为这时长度为1的序列,已经排序好了。我们不需要任何操作。
这里讲一下具体操作:将要排序的一组数分成两堆(这里我们选取中间点为划分标准),然后我们从两堆中的第一个元素比较,小的(或者大的,这里要求我们是降序还是升序排列)就放到一个新开的数组里面,来保存我们所需要的答案。

#include<stdio.h>
void MERGE(int *num,int p,int q,int r)
{int n1,n2;//两边各多少个元素 n1=q-p+1;n2=r-q;int am[50]={0};int ab[50]={0};for(int i=0;i<n1;i++){am[i]=num[p+i];}am[n1]=0x3f3f3f3f;//作为结束的哨兵for(int i=0;i<n2;i++){ab[i]=num[q+1+i];}ab[n2]=0x3f3f3f3f;int j=0;int i=0;//分别是两个待排序数组的下标for(int k=p;k<=r;k++)//从p到r,保证了所有元素都被排序{if(am[i]<=ab[j]){num[k]=am[i];i++;}else{num[k]=ab[j];j++;}}
}
void MERGE_SORT(int *num,int p,int r)
{if(p<r){int q=(p+r)/2;MERGE_SORT(num,p,q);MERGE_SORT(num,q+1,r);MERGE(num,p,q,r);}
}
int main(void)
{int num[50]={96,1,2,3,66,805,45,63,67,59,57,50,52,23,24};//15个printf("排序前\n");for(int j=0; j<=14; j++){printf("%d ",num[j]);}putchar('\n');MERGE_SORT(num,0,14);printf("排序后\n");for(int j=0; j<=14; j++){printf("%d ",num[j]);}putchar('\n');}
`

归并排序以及三种常见优化相关推荐

  1. 服务器三种常见的限流算法

    服务器三种常见的限流算法 1.计数器算法 2. 滑动窗口 3.令牌桶算法 4.漏桶算法 滑动窗口限流 漏桶限流 令牌桶限流 限流算法总结 单机限流和分布式限流 限流组件 在开发高并发系统时,有三把利器 ...

  2. html中选择样式,html中css三种常见的样式选择器 zz

    1:标签选择器 标签选择器,是所有带有某种标签的都生效.这里以p为例,也就是所有的带有p标记的都会这样的样式 p{font:"宋体"; color:#FF0000} 我现在表现的是 ...

  3. 三种常见的Python赋值表达式的写法!

    Python的赋值表达式英文原名为Assignment Expressions,因为它太像海象了所以又被称为海象运算符.今天小千就来给大家介绍一下三种常见的赋值表达式的写法,大家来了解一下以防将来遇到 ...

  4. C语言三种常见排序算法

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105112802 三 ...

  5. xp系统蓝屏代码7b_遇到系统问题,三种常见处理方法你更pick谁

    使用恢复功能之前请务必备份好数据,一旦操作可能导致数据无法恢复!!!卡慢.蓝屏.进不去系统?系统出现故障了,是拜托朋友还是外出花钱?求人不如求己,遇到系统问题 , 三种常见处理方法你更pick谁? 0 ...

  6. 深入学习jQuery的三种常见动画效果

    前面的话 动画效果是jQuery吸引人的地方.通过jQuery的动画方法,能够轻松地为网页添加视觉效果,给用户一种全新的体验.jQuery动画是一个大的系列,本文将详细介绍jQuery的三种常见动画效 ...

  7. php给html传值,PHP传值到不同页面的三种常见方式及php和html之间传值问题_PHP

    在项目开发中经常见到不同页面之间传值在web工作中,本篇文章给大家列出了三种常见的方式. 接触PHP也有几个月了,本文总结一下这段日子中,在编程过程里常用的3种不同页面传值方法,希望可以给大家参考.有 ...

  8. java常见的ide_在三个Java IDE中生成的三种常见方法

    java常见的ide 在本文中,我研究了NetBeans 8.0.2 , IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种"通用"方法[ e ...

  9. 在三个Java IDE中生成的三种常见方法

    在本文中,我研究了NetBeans 8.0.2 , IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种"通用"方法[ equals(Objec ...

最新文章

  1. android 耳机红外线,红外线耳机制作方法
  2. 利用 Vmware 安装 Linux 虚拟机
  3. [书籍分享]0-003.你的灯亮着吗:发现问题的真正所在
  4. 老员工在线“黑”华为:早期手机难看丢人 习惯另外带苹果三星
  5. linux java xmx_linux应用实际内存大于 jvm xmx
  6. 华为交换机重制_华为交换机重置命令
  7. pypdf2 存储pdf_PyPDF2:用于PDF文件操作的Python库
  8. 10个修复ie6下bug技巧[转]
  9. 心电电路算法滤波_简述心电信号采集原理及电路设计
  10. Keil4 新建工程 和 烧录程序
  11. Unity Shader 标准光照模型——漫反射
  12. Python第五周作业之选择题
  13. vue-router 如何在新窗口打开页面
  14. python request下载文件时、显示进度以及网速_实时网速显示_实例_python
  15. 呆老大,奸老二,家家有个坏老三(转载自:http://soulogic.3322.org/blog/read.php/165.html)
  16. 2015小米校招技术类笔试题
  17. 流程图-一些要点总结
  18. 通过宏代码自动解除excel工作表格保护
  19. python中文词频排序_python统计词频并排序
  20. python quit函数_在Python中启用quit函数的问题

热门文章

  1. 基于OpenCV的网络实时视频流传输
  2. Nginx 安装及配置
  3. 前端性能优化之gzip
  4. JDK, JRE和JVM的区别与联系
  5. 详细故障排除步骤:针对 Azure 中到 Windows VM 的远程桌面连接问题
  6. URL和URI的区别 【转】
  7. [转]PDO防注入原理分析以及使用PDO的注意事项
  8. 《.NET应用架构设计:原则、模式与实践》新书博客--试读-2.1.2 设计原则实战
  9. 海思下载uboot,内核,文件系统
  10. java ftp下载文件源码_java实现ftp文件下载的源代码