归并排序java(内附超详解图文讲解)

article/2025/11/7 1:02:10

目录

归并排序介绍:

归并排序图解:

示意图1

示意图2

归并排序详细步骤:

1.组合

2.分组

完整代码



归并排序介绍:


归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide- and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

归并排序图解:

示意图1


归并排序思想示意图1-基本思想:

示意图2

归并排序思想示意图2-合并相邻有序子序列:
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后- -次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤:

归并排序详细步骤:

归并排序的应用实例:
给你一个数组,  arr= Array(8, 4,5,7, 1,3,6,2),请使用归并排序完成排序。

为了便于大家理解 我把步骤分开:

先把最难的组合部分写完

1.组合

1.我们先写黑框的代码,也就是数组已经成为(4, 5,7,8, 1,2,3,6) 我们如何把它合成1 2 3 4 5 6 7 8

可以看一下示意图2

package suanfa;import java.util.Arrays;
import java.util.Scanner;public class xishuarr {public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};//假设已经到最后一步int arrys[]= {4 ,5 ,7 ,8,1 ,2, 3, 6};int[] add=new int[8];//第一个参数表示传入数组{4 ,5 ,7 ,8,1 ,2, 3, 6}//第二个参数表示这个数组的第一个位置 即是0//第三个参数表示这个数组的中间位置  (0+7)/2=3//第四个参数 存放临时数组的merge(arrys,0,3,7,add);}/*** * @param arr  排序的原始数组* @param left  左边有序序列的初始索引* @param mid   中间索引* @param right    右边索引* @param temp    做中转的数组*///4 5 7 8   1 2 3 6public static void merge(int[] arr,int left,int mid,int right,int[] temp) {int i=left;  //初始i,左边有序序列的初始索引int j=mid+1;  //初始j,右边有序序列的初始索引int t=0;       //指向temp数组的当前索引//1.//先把左右两边(有序)的数据按照规则填充到temp数组//直到左右两边的有序序列,有一边处理完毕为止while(i<=mid&&j<=right) {if(arr[i]<arr[j]) {temp[t]=arr[i++];/*** 这里我们这里是:temp[t]=arr[i++];* 如果不好理解,你可以写成这样:* temp[t]=arr[i];i++;*/}else {temp[t]=arr[j++];}//因为无论执行if里面的语句还是else里面的语句,t都要加1,所以把t移出来.t++;}//2.//把有剩余数据的一边的的数据依次全部填充到temp//由上述循环条件:i<=mid&&j<=right 可知 //此时要么要么j>right i>mid while(i<=mid) {temp[t]=arr[i];t++;i++;}while(j<=right) {temp[t]=arr[j];t++;j++;}//3.//把temp的数组转移到arr上int n=0;while(n<arr.length){arr[n]=temp[n];n++;}System.out.println(Arrays.toString(arr));}}

运行结果:

2.分组

写黑框里面的代码:

又回到初始,我们如何从把数组分成 黑框这样子呢?

 运用了递归的思想进行分:

方法:

	/*** 分* @param arr  排序的原始数组* @param left  左边有序序列的初始索引* @param right    右边索引* @param temp    做中转的数组*/public static void mergeSort(int[] arr,int left,int right,int[] temp) {//求中间索引int mid=(left+right)/2;if(left<right) {//左边递归分解mergeSort(arr,left,mid,temp);//右边递归分解mergeSort(arr,mid+1,right,temp);System.out.println(" 最左边索引:"+left+"\t最右边边索引:"+right+"\t"+Arrays.toString(arr));}}

主函数:

	public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};//假设已经到最后一步int arrys[]= {4 ,5 ,7 ,8,1 ,2, 3, 6};int[] add=new int[8];//第一个参数表示传入数组{4 ,5 ,7 ,8,1 ,2, 3, 6}//第二个参数表示这个数组的第一个位置 即是0//第三个参数表示这个数组的中间位置  (0+7)/2=3//第四个参数 存放临时数组的
//		merge(arrys,0,3,7,add);mergeSort(arr,0,7,add);}

结果:

 

或许有一部分同学,看到 结果会有疑问。那就是 你递归基础比较差,别怕,我给你做详细讲解。

如果没有问题的,可以跳过以下疑问:

疑问1:为啥数组没有变化?

因为 我们只是分,而没有改变数组的位置

疑问2:为啥为输出7次?

如下图所示,我们总共分了7次,所以输出7次

 疑问3:最左边索引 和 最右边索引 是啥意思?

 这是为了方便大家理解 递归的顺序 特意加上去的

第一行的  左:0  右:1      表示:  最左边索引为:0  最右边索引为:1

然后你再看下图:

故此递归的顺序:

相信此时,同学们会加深对递归的顺序的了解

我们来,分析一下,我们完成的部分:

 我们完成了 数组 的部分,然后→   治(组合)  我们是把 2个含4个有序数字组合成 1个有序的数组。

我们可以把先前的   治(组合)从原来:把 2个含4个有序数字组合成 1个有序的数组。修改成:

把 2个含n个有序数字组合成 1个有序的数组

不理解的话,看图:

 这是我们开头组合的:

那么以下这2步 和上面那个图的区别在于:

上图:2个含有4个有序数字 组成一个有序数组

下2个图:2个含有2个有序数字 组成一个有序数组

故此:

 我们把之前只适用一种情况的代码修改成通用的

之前的:

通用的:

	//3.//把temp的数组转移到arr上int n=0;int tempLeft=left;while(tempLeft<=right){arr[tempLeft]=temp[n];n++;tempLeft++;}

改好后我们在分的方法中 加入组合:

这样就能实现 每分一次 组合一次

完整代码

import java.util.Arrays;
import java.util.Scanner;public class xishuarr {public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};int[] add=new int[arr.length];System.out.println("排序前:"+Arrays.toString(arr));System.out.println("排序过程:");mergeSort(arr,0,add.length-1,add);System.out.println("排序后:"+Arrays.toString(arr));}/*** 分* @param arr  排序的原始数组* @param left  左边有序序列的初始索引* @param right    右边索引* @param temp    做中转的数组*/public static void mergeSort(int[] arr,int left,int right,int[] temp) {//求中间索引int mid=(left+right)/2;if(left<right) {//左边递归分解mergeSort(arr,left,mid,temp);//右边递归分解mergeSort(arr,mid+1,right,temp);merge(arr,left,mid,right,temp);System.out.println(" 最左边索引:"+left+"\t最右边边索引:"+right+"\t"+Arrays.toString(arr));}}/*** * @param arr  排序的原始数组* @param left  左边有序序列的初始索引* @param mid   中间索引* @param right    右边索引* @param temp    做中转的数组*///4 5 7 8   1 2 3 6public static void merge(int[] arr,int left,int mid,int right,int[] temp) {int i=left;  //初始i,左边有序序列的初始索引int j=mid+1;  //初始j,右边有序序列的初始索引int t=0;       //指向temp数组的当前索引//1.//先把左右两边(有序)的数据按照规则填充到temp数组//直到左右两边的有序序列,有一边处理完毕为止while(i<=mid&&j<=right) {if(arr[i]<arr[j]) {temp[t]=arr[i++];/*** 这里我们这里是:temp[t]=arr[i++];* 如果不好理解,你可以写成这样:* temp[t]=arr[i];i++;*/}else {temp[t]=arr[j++];}//因为无论执行if里面的语句还是else里面的语句,t都要加1,所以把t移出来.t++;}//2.//把有剩余数据的一边的的数据依次全部填充到temp//由上述循环条件:i<=mid&&j<=right 可知 //此时要么i>mid 要么j>rightwhile(i<=mid) {temp[t]=arr[i];t++;i++;}while(j<=right) {temp[t]=arr[j];t++;j++;}//3.//把temp的数组转移到arr上int n=0;int tempLeft=left;while(tempLeft<=right){arr[tempLeft]=temp[n];n++;tempLeft++;}}}

结果:

来自:【尚硅谷】数据结构与算法(Java数据结构与算法)_哔哩哔哩_bilibili


http://chatgpt.dhexx.cn/article/xiJ15Nbr.shtml

相关文章

java实现归并排序(详解)

主要思想 归并排序和快速排序都是基于分而治之的算法思想。 归并排序先将待排序的数组不断拆分&#xff0c;直到拆分到区间里只剩下一个元素的时候。不能再拆分的时候。这个时候我们再想办法合并两个有序的数组&#xff0c;得到长度更长的有序数组。当前合并好的有序数组为下…

Launcher3--抽屉

抽屉是用来放置安卓手机中所有需要显示到Launcher上的(当然也可以进行过滤&#xff0c;将不想显示的隐藏起来)应用和小部件&#xff0c;启动应用、添加快捷方式到桌面、卸载等。之前也提到过&#xff0c;有些Launcher是没有抽屉的&#xff0c;如MIUI的Launcher。在Launcher3中&…

Android launcher3 开发初始篇

版本&#xff1a;1.0 日期&#xff1a;2014.8.26 2014.8.27 2014.11.10 版权&#xff1a;© 2014 kince 转载注明出处 好久没有写博客&#xff0c;也是因为工作比较忙的关系。当然这不是理由&#xff0c;主要是很多bug要改&#xff0c;而自己的效率又不是很高&#xff0c;…

安卓Launcher 简介

转载请注明出处&#xff1a;安卓Launcher 简介_安卓launcher是什么_Mr_Leixiansheng的博客-CSDN博客 文章概述&#xff1a; 1.什么是Launcher 2.新建一个Launcher工程 3.Apps去哪了 4.显示桌面背景 最近换了新工作(๑ㅁ)&#xff0c;又是要去接触新的知识了。闲话不多说&…

android12.0(S) Launcher3 细节修改

去除 Launcher3 底部类似 dockbar 条目 packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java availableHeightPx windowBounds.availableSize.y;mInfo info; - isTablet info.isTablet(windowBounds);//isTablet info.isTablet(windowBounds);is…

Launcher3

Android 4.4 (KK)开始Launcher默认使用Launcher3&#xff0c;Launcher3较Launcher2 UI 有部分调整&#xff0c;主要包括: &#xff08;1&#xff09; 状态栏透明&#xff0c;App List 透Wallpaper&#xff1b; &#xff08;2&#xff09; 增加overview模式&#xff0c;可以调整…

Launcher3 模块的简单设计

Launcher3 模块的简单设计 Lancher3 路劲&#xff1a; Z:\xxx\packages\apps\Launcher3 任务 1、AllApps背景透明化。 2、Allapps前3个图标变为Chrome、youtube、play商店。 3、长按桌面空白处在弹出的按钮下添加一个图标变大按钮&#xff0c;一个图标变小按钮&#xff0c;点…

android12.0(S) Launcher3 导入 AndroidStudio 调试编译

验证环境 aosp 12.0 源码&#xff0c;分支 android-12.0.0_r3 可以参考之前写的 android12.0(S) Pixel 3XL (QCOM 845) 编译刷机 AndroidStudio 版本 Android Studio Arctic Fox | 2020.3.1 Patch 4 gradle 版本 gradle-7.0.2-bin.zip gradle:7.0.4 二手 Pixel 3 XL一台可直…

launcher3的具体学习

目录结构&#xff1a; allapps 目录&#xff1a;主要存放主菜单界面相关代码。 anim目录&#xff1a;存放动画相关&#xff0c; badge目录&#xff1a;存放图标标识相关 compat目录&#xff1a;存放解决兼容性相关。 config目录&#xff1a;配置Launcher相关功能的宏开关 dragn…

Android10/11 原生Launcher3深度定制开发

一、引言 关于Android10和11系统Launcher3的定制有很多&#xff0c;根据项目的需求会进行各种定制开发&#xff0c; 于是就需要研究Launcher3的源码。本文主要从Android 11的Launcher3QuickStep着手 &#xff08;go版本或者其他版本类似&#xff09;从常用的修改进行分析&#…

Launcher3-桌面布局+主要的类+启动流程

一、launhcer3桌面布局二、launcher3主要的类LauncherModel&#xff1a;BubblTextView&#xff1a;DragController&#xff1a;LauncherAppState&#xff1a;DragView&#xff1a;DragSource&#xff0c;DropTarget&#xff1a;Folder&#xff1a;FolderIcon&#xff1a;Launch…

Launcher3--初识Launcher3

一、Launcher简介 Launcher时开机完成后第一个启动的应用&#xff0c;用来展示应用列表和快捷方式、小部件等。Launcher作为第一个(开机后第一个启动的应用)展示给用户的应用程序&#xff0c;其设计的好坏影响到用户的体验&#xff0c;甚至影响用户购机的判断。所以很多品牌厂商…

Android Launcher3分析及定制主题实现

一. Launcher3 简介 **launcher3是在Launcher2的基础上进化的版本,从Android 4.4 开始就使用Launcher3 .(kk版,kk2版)作为桌面使用,以前我们都在使用Launcher2,我们使用的是KK版本,具体区别后面再说. ** 1 Launcher3 桌面变成了动态管理,launcher2 里面默认最多加载五个worksp…

Android Launcher3简介

一.Launcher3概述 Launcher顾名思义&#xff0c;就是桌面的意思&#xff0c;也是android系统启动后第一个启动的应用程序&#xff0c;这里以android11为例&#xff0c;和其他应用并无区别&#xff0c;只是增加了对其他app和widget的管理窗口&#xff0c;且可以为用户定制化一些…

详细理解准确率、精准率、召回率,F1值等评价指标的含义

转载文章 原博客地址&#xff1a;详解准确率、精确率、召回率、F1值等评价指标的含义 机器学习问题之中&#xff0c;通常需要建立模型来解决具体问题&#xff0c;但对于模型的好坏&#xff0c;也就是模型的泛化能力&#xff0c;如何进行评估&#xff1f;我们可以定一些评价指标…

详解准确率、精确率、召回率、F1值等评价指标的含义

机器学习问题之中&#xff0c;通常需要建立模型来解决具体问题&#xff0c;但对于模型的好坏&#xff0c;也就是模型的泛化能力&#xff0c;如何进行评估呢&#xff1f; 很简单&#xff0c;我们可以定一些评价指标&#xff0c;来度量模型的优劣。比如准确率、精确率、召回率、…

分类性能评价指标——精确率,召回率,F1值详细解释

分类性能的评价指标 准确率 准确率是全部参与分类的文本中&#xff0c;与人工分类结果吻合的文本所占的比例。 即&#xff1a;预测与真实标签相同的比例 A c c u r a c y T P T N T P T N F P F N Accuracy\frac{TPTN}{TPTNFPFN} AccuracyTPTNFPFNTPTN​ 精确率 也称…

准确率、精确率、召回率、F1值

1.TP、TN、FP、FN 先粘一个官方形式的。 用新冠来举例理解。下方正方形为样本&#xff0c;其中 圆的部分认定为检测后是阳性的&#xff0c;其余部分为检测为阴性的&#xff08;但是现在的情况是检测并不完全准确&#xff0c;有可能检测时阴性&#xff0c;但实际上已经有新冠…

机器学习中的二分类问题评价指标之精确率、召回率、F1值通俗理解

引言&#xff1a;对于分类问题&#xff0c;我们在评估一个模型的好坏时&#xff0c;通常想到的是把该模型在测试集上分类结果正确的样本数量比上测试集的样本数量的比值结果&#xff0c;即准确率&#xff08;精确率&#xff09;作为评价准则。但除此之外&#xff0c;还有精确率…

【转】一些因素对F1值的影响

截自&#xff1a;https://blog.csdn.net/qq_27590277/article/details/88374695 https://blog.csdn.net/qq_27590277/article/details/88367082 一些因素对F1值的影响 如果还没了解F1值的话&#xff0c;这里有我之前写的通俗易懂的文章 详谈P(查准率)&#xff0c;R(查全率)&…