学习笔记-数据结构与算法-归并排序

数据结构与算法之美 | 学习笔记09 ——归并排序&快速排序 归并排序和快速排序都用到了分治思想,的时间复杂度都为O(nlogn)O(nlogn)O(nlogn),适合大规模的数据排序。 一、归并排序(Merge Sort) 1. 归并排序实现 分治算法一般都是用递归来实现的,分治是解决问题的处理思想,递归是一种编程技巧。用递归来代码实现归并排序,首先写出递推公式的伪代码: 递推公式: merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r)) //下标p到r之间的数组排序,转化为p到q和q+1到r的数组排 阅读详情

归并排序核心思想:

将一个数组一分二,然后将两个数组分别排序,最后将两个有序数据合并,就完成了归并排序。

归并排序使用的是分治思想,分而治之,将一个大问题分解为n个小问题,小问题解决了,大问题也就解决了。

归并排序一般使用递归来实现,要写出递归代码的关键,写出递推公式,找到终止条件。

归并排序的递推公式:

merge_sort(p…r) = merge(merge_sort(p…q),merge_sort(q+1….r))

终止条件:q>= r

递推公式注释:

merge_sort(p…r)表示我们要排序的数组的下标在p…r区间,将这个大的数组的排序问题转化为了两个子数组排序的问题。即排序p到q区间和q+1到r区间,q=(p+r)/2,当这两个数组排序完成后,使用merge合并函数进行数组的合并,整个数组即可为有序。

再来说说merge合并函数

还是先画个图

 

代码实现

public class MergerSort<T> implements SortInf<T> {

 
@Override
 
public void sort(T[] data) {

   
if (null == data || data.length <= 1) {
     
return;
   
}
   
if (!(data[0] instanceof Comparable)) {
     
throw new IllegalArgumentException("data not implement compator interface");
   
}

   
// 1,归并排序操作
   
recurstion(data, 0, data.length - 1);
 
}

 
private void recurstion(T[] data, int start, int end) {
   
// 递归的终止条件
   
if (start >= end) {
     
return;
   
}

   
// 1,找到中间的索引位置
   
int midIndex = (start + end) / 2;
   
// 进行左半边数据递归操作
   
recurstion(data, start, midIndex);
   
// 进行右半边数据递归操作
   
recurstion(data, midIndex + 1, end);

   
// 进行mergesort的合并操作
   
merget(data, start, midIndex, midIndex + 1, end);
 
}

 
/**
   *
进行数据的合并操作
  
*
   * @param
data 原始数据
  
* @param leftstart 左开始索引
  
* @param leftEnd 左结束索引
  
* @param rightStart 右边开始索引
  
* @param end 右边结束索引
  
*/
 
private void merget(T[] data, int leftstart, int leftEnd, int rightStart, int end) {

   
int dataLength = end - leftstart + 1;

   
// 声明一个目标的数组大小
   
T[] target = (T[]) Array.newInstance(data[0].getClass(), dataLength);
    int
tarIndex = 0;

    int
leftIndex = leftstart;
    int
rightIndex = rightStart;

    while
(leftIndex <= leftEnd && rightIndex <= end) {
     
// if i < j ? -1  == 0 > 1
     
if (((Comparable) data[leftIndex]).compareTo(data[rightIndex]) > 0) {
        target[tarIndex++] = data[rightIndex++]
;
     
} else {
        target[tarIndex++] = data[leftIndex++]
;
     
}
    }

   
// 将剩余的值拷贝到目标数组中
   
if (leftIndex <= leftEnd) {
     
for (int i = leftIndex; i <= leftEnd; i++) {
        target[tarIndex++] = data[i]
;
     
}
    }
else if (rightIndex <= end) {
     
for (int i = rightIndex; i <= end; i++) {
        target[tarIndex++] = data[i]
;
     
}
    }

   
// 将数据拷贝回原数组中
   
for (int i = leftstart; i <= end; i++) {
      data[i] = target[i - leftstart]
;
   
}

    System.
out.println(Arrays.toString(data));
 
}
}

 

如何分析归并排序的时间复杂度

在递归的场景中,一个问题a可以分解为几个子问题b和c,将问题b和问题c求解后,再将问题b和问题c的结果合并,就可以得到问题a的求解

定义求解的问题,a的时间为t(a),求解b、c的时间时间分为别t(b)和t(c),合并t(b)和t(c)的时间为k,代入递推公式就各要得到:

t(a)=t(b)+t(c)+k

在归并排序中,每次都将数据一分为二,可以表示为n/2,merge合并函数每次都需要将n个数据合并,可以表示为n,递推关系式可以改写为为:

t(n)=2*t(n/2)+n

t(1)=C,,当求解的数组大小为1时,只需要常量级的时间,所以表示为C

 

可获得结果

再次计算

结果

 

再次计算

结果

 

总结规律

 

可得到

可得到k的取值

t(1)=C

将k代入

 

使用O表示法就是

 

归并排序的总结:

算法名称

最好情况时间复杂度

最好情况的原始数据

最坏情况时间复杂度

最坏情况的原始数据

平均情况时间复杂度

是否基于比较

空间复杂度

是否稳定排序算法

归并排序

O(nlogn)

与原始数据的有序度无关

O(nlogn)

与原始数据有序度无关

O(nlogn)

是

O(n)

非原地排序算法

移定的原地排序算法。

 

 

 

 

 

 

 

 

Skynet 框架面试题 本文整理了游戏服务端开发面试中 Skynet 框架的高频考点,涵盖底层架构、消息派发、协程调度、网络 I/O、harbor 跨机通信、内存管理、socket 处理、阻塞操作、错误处理等核心内容。全面覆盖 Skynet 框架的原理、使用和实战问题,追求深入准确,拒绝八股文。 阅读详情

相关推荐

Unity特效序列帧输出全攻略:Recorder+Timeline保姆级教程(解决透明通道问题)

本文提供Unity特效序列帧输出的完整解决方案,重点讲解如何结合Recorder与Timeline工具,实现带透明通道的PNG序列帧高效输出。通过保姆级教程,详细解析摄像机隔离、层级设置、参数配置等关键步骤,并深度解决透明通道丢失等常见问题,帮助特效师和动画师打通引擎创作与后期合成的工作流。

tensorflowjs6的博客 429

数组分成两个尽量相等的子数组

类似于0-1背包问题 将一个数组分成两部分,不要求两部分所包含的元素个数相等,要求使得这两个部分的和的差值最小。比如对于数组{1,0,1,7,2,4},可以分成{1,0,1,2,4}和{7},使得这两部分的差值最小。 思路: 这个问题可以转化为求数组的一个子集,使得这个子集中的元素的和尽可能接近sum/2,其中sum为数组中所有元素的和。这样转换之后这个问题就很类似0-1背包问题了:在...

漆灿 6354

GitLab中国区注册终极解决方案:绕过+86手机验证的实战技巧(2023最新)

本文详细解析了GitLab中国区注册时绕过+86手机验证的三种实战技巧,包括开发者工具调试方案、使用国际号码的变通方案以及本地化部署替代方案。通过技术分析和实践验证,帮助开发者顺利注册GitLab账号,提升团队协作效率。

rl6adventurer的博客 1490

一个数组分割成2个数组

分割数组

PEACEMINUSON的博客 688

Adams二次开发实战指南:从CMD到Python与插件开发全解析

本文全面解析Adams二次开发的三种核心方法:CMD命令、Python脚本和C++插件开发。通过实战案例展示如何实现参数批量修改、自动化仿真流程和定制功能开发,显著提升多体动力学仿真效率。特别适合需要处理复杂建模和重复性任务的工程师学习参考。

weixin_29235923的博客 125

第95章 安全工程师:Shell 脚本实现安全扫描、漏洞检测、日志审计

随着网络安全威胁日益复杂,传统的手动安全管理已无法满足现代企业的安全需求。Shell 脚本为安全工程师提供了强大的自动化能力,能够实现 7×24 小时的安全监控、快速漏洞扫描、智能日志分析和实时威胁响应。本章将系统介绍如何使用 Shell 脚本构建完整的安全防护体系,从基线检查到实时监控,帮助你打造自动化的安全运维能力。

猪猪侠 90

LeetCode 2035. 将数组分成两个数组并最小化数组和的差

三分枚举

英雄哪里出来 4255

【SMPL简介】SMPL: A Skinned Multi-Person Linear Model【源码复现】

SMPL是一种3D人体建模方法.在数字人或者人物角色三维重建领域有着广泛应用支持人体的各种形状及动作可以简单理解为通过训练获取的人物模型SMPL 输入是:姿态shape vectorβ\betaβ+ 影响动作Pose的参数θ\thetaθ输出是: 各种变化后vertex顶点的数据作者:Loper, Matthew and Mahmood, Naureen and Romero, Javier and Pons-Moll, Gerard and Black, Michael J.

zik的博客 3369

动态规划-将数组分成两个数组,并最小化数组和的差(java)

每到一个数,有选择和不选两种情况,分开讨论,返回最逼近sum/2 的最大值.尽量让两个集合的累加和接近 返回最接近的情况下,较小集合的累加和。我们先求出数组的累加和sum.然后拆分数组时,让较小集合去逼近。给定一个正数数组arr, 请把arr中所有的数分成两个集合,sum/2.这样得出的数组就是符合要求的.动态规划就是对递归的改写,还是三个步骤.1.根据base case 初始化dp表。2.递归过程改成从表中拿数据的过程。3.返回递归调用的最初始状态。

SP_1024的博客 1140

Open3d Qt的环境配置

目前统一使用qt6配置,open3d中可视化功能目前使用vtk代替,语言为c++。

阁楼 919

AI快速变现之路,AI视频创作

初期投入$3000(工具订阅+样片制作),重点攻克跨境电商和本地生活服务市场。关注2025年AIGC视频工具的API降价趋势(如Pika企业版折扣可达50%),建议与云服务商签订长期合作协议。

qq_29896351的博客 1981

2023-07-04:给定一个数组A, 把它分成两个数组B和C 对于数组A每个i位置的数来说, A[i] = B[i] + C[i] 也就是一个数字分成两份,然后各自进入B和C 要求B[i], C[i

2023-07-04:给定一个数组A, 把它分成两个数组B和C对于数组A每个i位置的数来说,也就是一个数字分成两份,然后各自进入B和C要求B[i], C[i] >= 1最终B数组要求从左到右不能降序最终C数组要求从左到右不能升序比如可以分成这是一种有效的划分返回有多少种有效的划分方式1

福大大架构师每日一题 1万+

AI上推荐 之 协同过滤

㐇

Miracle8070 1万+

数据结构与算法学习笔记----归并排序

请你使用归并排序对这个数列按照从小到大进行排序。并将排好序的数列按顺序输出。输出一个整数,表示逆序对的个数。个整数(整数均在1~10。个整数(整数均在1~10。,表示整数序列元素个数。范围内),表示整个序列。个整数,排序好后的序列。数列中的元素的取值范围。,表示整数序列元素个数。范围内),表示整个序列。数列中的元素的取值范围。

weixin_60278491的博客 706

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

数据结构与算法学习笔记——快速排序、归并排序

快速排序 快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 实现思路 代码实现 import java.util.Arrays; public class QuickSort { public static void main(String[] args) { in

qq_29384339的博客 427

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构与算法学习笔记——归并排序、快速排序

归并排序 原理 归并排序是用了分而治之的思想,原理对照下边我画的图看很简单,将数组分成前后两部分,然后分别对这两部分排序,排序好之后再合并起来。 而在代码中我们需要用到递归来实现。众所周知,递归先要找到递推公式和终止条件。 递推公式:sort(start, end) = merge(sort(start, mid), sort(mid + 1, end); 终止条件:start >...

TrZoey的博客 364

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C#数据结构与算法学习笔记 归并排序

1.归并排序的归并过程 2.归并排序及递归调用 3.归并排序优化

Mr_Tfos的博客 206

数据结构与算法-学习笔记(12)-归并排序

菜鸟一枚, 刚刚学习数据结构与算法, 为了加深理解, 所以与同学们分享学习过程。 今天学习的是, 归并排序!!! 上代码: #include <stdio.h> void merge(int arr[],int L,int M,int R) //合并两个数组 { int LEFT_SIZE = M - L; int RIGHT_SIZE =R - M + 1; ...

qq_43765237的博客 309

数据结构与算法学习笔记——排序算法(六):归并排序

1、介绍 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修 补"在一起,即分而治之)。 2、算法分析 (1)分解:每次把数组分均分为两份,利用递归的方法分解数组,直至每个小数组为1个大小。 (2)合并相邻有序子序列:再来看看治阶段,将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并

最初的模样 368

数据结构与算法学习笔记十 --- 归并排序算法

归并排序算法(Merge Sort) 归并排序算法是一种递归排序算法,其原理是:先将序列进行递归分解,分解到不能再分解为止;然后在进行相邻的两两排序合并,最后完成排序。 一般归并排序算法的递归分解,是使用折半分解。 以序列 – [54, 26, 93, 17, 77, 31, 44, 55, 20] 为例 流程可以参考下图: 其中merge_sort()表示分解,result表示返回排序好的合并序...

Hajo 342

算法与数据结构学习笔记(17):排序之归并排序

语法: CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回类型 BEGIN 函数体 END 注:1.参数列表包含两部分:参数名和参数类型 2.函数体:必须有return语句,否则会报错。 3.若函数体中仅有一条语句,则可以省略BEGIN END 4.使用delimiter语句设置结束标记 ...

光脚小孩的博客 161

《数据结构与算法——C语言实现》学习笔记——归并排序

/************************************************** * Copyright(C): * Filename:merge_sort.cpp * Author: * Version: * Data: 18 sep 2013 * Description: **********************************************

sduzh的专栏 802

数据结构与算法学习笔记(六)插入、希尔、归并排序

排序算法

xueguchen的博客 545

《数据结构与算法》学习笔记9 希尔排序、归并排序

待定

qq1977261418的博客 259

《数据结构与算法》学习笔记20 递归_归并排序

//比简单排序效率高  大o表示法分别是:O(n^2)>O(n*logn),但是比较占用内存 public class DArray { private long[] a; private int size; public DArray(int n){ a=new long[n]; size=0; } public void inse

qq1977261418的博客 299

学习笔记(14):算法&数据结构-归并排序——归并

您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】 本课程从最基础的时间、空间复杂度概念入手,深入浅出的讲解常用排序、查找算法,通过本课程的学习,我们希望能帮你建立起算法思维,使你在以后的项目开发不断思考如何通过更优的算法来提高程序运行效率,且有能力写出适合你业务逻辑的算法程序。 为什么学习这个课程? 很多...

qq_34288612的博客 224
上一篇: 学习笔记-数据结构与算法-插入排序
下一篇: 二分查找
null_null_bug
博客等级 码龄7年 72粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值