归并算法

2023-10-26

归并算法
1.在解释算法优缺点的时候,首先要提到2点,一是比较的次数,二是数据要改变或移动的次数。第一个比较好理解,那什么叫改变和移动的次数呢?比如说2这个数据在存储上存储的是10,如果现在2变成4,那么存储就变成了100,这个过程需要将2向左移动一位,那么就叫移动一次,如果是2变成8,那么就需要移动2次。在实际运算过程中不会考虑这么细致。
2.归并算法是排序算法中的第五种,前四种依次是:冒泡,选择,插入,快速。
3.归并的核心思想是分治。分治顾名思义就是分开治理,假设一个问题,有若干个小问题组成,那么分治就是先逐个击破每个小问题。(有点解高中物理,数学题的感觉)
4.归并算法的解释语言解释:如果你在网上去找一些归并算法的资料学习,那么你可能要茫然到最后不得不靠着阅读代码才能真正理解。所以有必要正真的用文字来描述下归并的全过程,毕竟直接阅读代码是晦涩难懂的。
假设一组数据有8个,一开始将这8个数据两两一组分成4组,然后对每组进行排序,这个地方叫做分治。然后第二次是将8个数据分成两组,每组4个数据,其中这4个数据分别是前两个和后两个已经有序,所以接下来的处理就是按照从左到右的顺序一个一个取出两组有序数据比较排列成一个有序数组,这个数组有4个数据。另外一边4个数据也是同样操作。这样就得到了一个左边和右边都有4个有序数据的数组,再按照以上操作,将这两组数据归并。
5.java代码

package algorithm.merge;

public class Merge {

	public static void main(String[] args) {
		int[] a = new int[]{4, 3, 6, 1, 2, 5, 8, 7};
        mergeSort(a, 0, 1);
        for (int i = 0; i < a.length; ++i) {
            System.out.print(a[i] + " ");
        }
	}
	/**
	 * 目的是将两个有序列表归并成一个有序表,这是一个分治点
	 * start 第一个有序表的起始索引
	 * mid  第二个有序表的起始索引
	 * end  第二个有序表的结束索引
	 */
	public static void merge(int[] target,int start,int mid,int end){
		int[] temp = new int[end-start+1];//一个临时数组,用来存储两个归并好的有序列表
		int indexS = start;//第一个有序表的索引
		int indexM = mid;//第二个有序表的索引
		int indexT = 0;//temp数组的索引
		//将两个有序表排列成一个有序表,直到其中的一个表数据取完,这时候将另一个表的剩余数据,一次添加到temp的尾部。
		while(indexS<mid && indexM<=end){
			if(target[indexS]<target[indexM]){
				temp[indexT++] = target[indexS++];
			}else{
				temp[indexT++] = target[indexM++];
			}
		}
		//如果第一个表还有数据
		while(indexS<mid){
			temp[indexT++] = target[indexS++];
		}
		//如果第二个表还有数据
		while(indexM<=end){
			temp[indexT++] = target[indexM++];
		}
		//将temp替换到原来target数组,从start的往后拷贝temp.length个数据
		//这个arraycopy方法是native修饰的,也就是说这个方法是从内存上直接copy的,效率特别高
		System.arraycopy(temp, 0, target, start, temp.length);	
	}
	/**
	 * length 每次归并的列表长度,开始为1
	 * 从0开始,
	 * 下面的例子按照8个长度数组举例子
	 */
	public static void mergeSort(int[] target,int start,int length){
		int size = target.length;//target数组总长度,用于计算分组数
		//例如第一次归并长度为1,那么就需要将数组分为4组,每组2个数据归并,所以将length向左移1位,也就是乘以2
		int group = size/(length<<1);//向下取整机制,假设是9个数,那么也是4组,就造成第9个数组未参与排序
		//当length==8的时候,那么group就等于0,此时结束算法(递归结束);
		if(group==0){
			return;
		}
		//循环将group组数据归并
		for(int i=0;i<group;++i){
			int s = i * 2 * length;
			//递归调用merge排序
			//当i=0时候merge(target,0,1,2);
			//当i=1时候merge(target,2,3,4);
			//当i=2时候merge(target,4,5,6);
			//当i=3时候merge(target,6,7,8);
			//也就是说当分4组的时候,0-2,2-4,4-6,6-8被分治排序。
			merge(target,s,s+length,(length<<1)+s-1);
		}
		//用总长度与每组长度取模运算,如果模为0代表数组的长度是2的整数次方,为最乐观情况下
		//如果模不为0意味着每次结束的时候余下的数都要与前面所有的数进行一次归并。
		//下面注释的代码为常规写法
//		 int mod = size%(length<<1);
//		 if(mod!=0){
//			 merge(target,0,(length<<1)*group,target.length-1);
//		 }
		
		//下面这段代码功能用途和上面的完全相同
		//这段代码运用的是&运算,效率上要高于注释的取模运算(神就在此处体现)
		//此处的运算,只有当length是2的指数幂时,结果是对的,其他一律错,正好这个地方必然是2的指数幂。
		int r = size & ((length << 1) - 1);
        if (r != 0){
            merge(target, size - r - 2 * length, size - r, size - 1);
        }
		mergeSort(target,0,length<<1);
	}

}
6.思考的问题
		a.当归并的数组长度不是2的指数次幂,是否可以通过补成2的指数次幂运算?
		b.当归并的数组长度不是2的指数次幂,是否可以去掉多余的数,当其余的归并成功后再插入?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

归并算法 的相关文章

  • Linux系统下安装Redis-7.0.0

    一 准备工作 1 下载安装新版的gcc编译器 redis的安装需要gcc环境的支持 所以首先要检查下服务器上时候已经安装了gcc环境 离线安装gcc包 执行安装命令 rpm ivh rpm nodeps force 1 1 下载Redis客

随机推荐

  • 前端面试题(js篇)

    1 解释一下什么是闭包 什么是闭包 函数使用了不属于自己的局部变量 函数套函数 里面函数使用了外面函数定义的变量 闭包的作用 避免全局污染 闭包的缺点 使用过多会造成内存泄漏 占用的内存释放不掉 2 js中的本地存储有哪些 区别是什么 1
  • QT日常报错解决方案

    日常报错 3 1 undefined reference to vtable vtable 表示的是虚表 这个错误出现时 请检查你的父类所有虚函数是否实现 或者子类是否把父类的虚函数都处理完 注意 析构函数也算 有时候一开始没有添加Q OB
  • 专业程序员开发-老狼孩插件懒人精灵版

    老狼孩插件懒人版 综合分类版 v1 7 5有新版啦 完全开放 免费使用 全新改版 1 优化 调试输出默认延迟1000毫秒 2 新增 更新类 阿里云json版热更新 定时关闭界面自动更新 无界面自动更新 3 新增 更新类 坚果云json版热更
  • 服务器太小是什么情况 显示小,服务器内存显示的比实际的小

    服务器内存显示的比实际的小 内容精选 换一换 弹性云服务器创建成功后 使用free m命令查询内存大小 查询结果与实际配置不符 较之创建时的配置要小一些 示例 假设创建该弹性云服务器时 配置的实际内存大小为4194304KB 即4096MB
  • QT之QChart的简介

    QT之QChart的简介 1 创建图表 2 设置图表标题和坐标轴标签 3 定制图表样式 4 显示图表 5 保存图表为图像 QChart 是 Qt Charts 模块中的一个主要类 用于创建和管理图表 QChart 提供了一组用于创建各种类型
  • Vue实现面包屑功能(el-breadcrumb)

    vue3 elementPlus 实现面包屑功能 文章后面附效果图 数据结构 首先展示一下数据基础结构 红色框框是默认存在的数据 其他数据就是通过选中侧边栏菜单进行数据插入 关键数据字段为 path meta 准备侧边栏 首先需要自己准备一
  • 常用对象类型之间的转换

    ads point 是原来的ADS 编程中定义的一种数据类型 其定义为 typedef ads real ads point 3 而ads real 则被定义为 typedef double ads real 可以看出 ads point
  • 前端知识14:webpack打包图片资源

    需要下载url loader 和 file loader两个包 前者依赖于后者 安装 npm i url loader file loader D 图片在css中使用的场景 注意图片在src目录下 注意图片路径的写法用的是相对路径 引用插件
  • C++ vector 容器浅析

    C STL 教程 C STL 教程 C vector 容器浅析 C vector 容器浅析 个人理解 vector就是一个模板类 具有元素多少可以变化的优点 一般为了根据数据类型 会选择显式实例化 下为一个利用vector模板 将一维数组转
  • 【华为OD统一考试B卷

    题目描述 一群大雁往南飞 给定一个字符串记录地面上的游客听到的大雁叫声 请给出叫声最少由几只大雁发出 具体的 1 大雁发出的完整叫声为 quack 因为有多只大雁同一时间嘎嘎作响 所以字符串中可能会混合多个 quack 2 大雁会依次完整发
  • blender 线框效果/Line Art

    Blender 2 93 新功能 Line Art 效果 哔哩哔哩 bilibilihttps www bilibili com video BV19Z4y1w7mk from search seid 1496511710922071136
  • 在Linux系统如何修改profile文件后立即生效呢?

    方法1 让 etc profile文件修改后立即生效 可以使用如下命令 etc profile 注意 和 etc profile 有空格 方法2 让 etc profile文件修改后立即生效 可以使用如下命令 source etc prof
  • go语言字符类型byte与rune

    字符串中的每一个元素叫做 字符 在遍历或者单个获取字符串元素时可以获得字符 Go语言的字符有以下两种 一种是 byte 型 是 uint8 的别名 代表了 ASCII 码的一个字符 另一种是 rune 类型 代表一个 UTF 8 字符 当需
  • Java中JDBC的数据库连接池

    数据库连接池 池参数 所有池参数都有默认值 初始大小 10个 最小空闲连接数 3个 增量 一次创建的最小单位 5个 最大空闲连接数 12个 最大连接数 20个 最大的等待时间 1000毫秒 四大连接参数 连接池也是使用四大连接参数来完成创建
  • 快速+完美+准确解决SpringBoot项目打包后的SNAPSHOT.jar中没有主清单属性的问题

    目录 问题再现 问题解决 结果 问题再现 xxxx 0 0 1 SNAPSHOT jar中没有主清单属性 问题解决 1 出问题的pom xml文件
  • 一个build脚本欣赏

    build scripts My basic build bat file looks like this echo off erase ThemeChanger exe copy Loader ArmRel Loader exe copy
  • Nginx安装

    目录 1 前期准备 2 将安装文件上传至安装目录 3 nginx安装 3 1安装openssl 3 2安装zlib 3 3安装pcre 3 4 安装nginx 4 nginx配置 4 1 检查nginx是否安装成功 4 2 nginx配置普
  • 怎么使用java servlet +jsp 实现一个简单的信息管理系统

    写之前看一下命名规范 数据库命名规范参考 Java命名规范参考 一 绪论 昨天 在群里看见一个大二学生叫帮忙代做Java课设 心怀着锻炼技术又可赚点零花钱就帮忙代做了 下面来说说怎么快速使用servlet jsp进行一个简单的信息管理系统搭
  • 20210715:力扣第1846题:减小和重新排列组合后的最大元素(java)

    题目 给你一个正整数数组 arr 请你对 arr 执行一些操作 也可以不进行任何操作 使得数组满足以下条件 arr 中 第一个 元素必须为 1 任意相邻两个元素的差的绝对值 小于等于 1 也就是说 对于任意的 1 lt i lt arr l
  • 归并算法

    归并算法 1 在解释算法优缺点的时候 首先要提到2点 一是比较的次数 二是数据要改变或移动的次数 第一个比较好理解 那什么叫改变和移动的次数呢 比如说2这个数据在存储上存储的是10 如果现在2变成4 那么存储就变成了100 这个过程需要将2