当前位置: 首页 > news >正文

排序第五篇 归并排序

一 简介

归并排序(Merge Sort) 的基本思想是: 首先将待排序文件看成 n n n 个长度为1的有序子文件, 把这些子文件两两归并, 得到 n 2 \frac{n}{2} 2n 个长度为 2 的有序子文件;

然后再把这 n 2 \frac{n}{2} 2n 个有序的子文件两两归并, 如此反复,直到最后得到一个长度为 n n n 的有序文件为止, 这种排序方法称为二路归并排序

在本文中,我们讨论的归并排序特指二路归并排序. 看一个示意图:
在这里插入图片描述

二 实现过程

归并排序的核心操作是将数组中前后相邻的两个有序序列归并为一个有序序列.
以java为例,看一个demo。

public class MergeSort {public static void main(String[] args) {Integer[] array = new Integer[]{30,45,10,30,50};System.out.println("归并排序初始顺序\n"+ Arrays.toString(array));mergeSort(array);System.out.println("归并排序最后顺序\n"+Arrays.toString(array));}static void mergeSort(Integer[] arr) {sort(arr, 0, arr.length - 1);}/**** 将两个有序序列归并为一个有序序列*/static void sort(Integer[] arr, int low, int high) {if (low >= high) {return;}int mid = low + (high - low) / 2;sort(arr, low, mid);sort(arr, mid + 1, high);merge(arr, low, mid, high);}static void merge(Integer[] arr, int low, int mid, int high) {//定义了一个临时数组int[] temp = new int[high - low + 1];int i = low, j = mid + 1, k = 0;while (i <= mid && j <= high) {temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];}while (i <= mid) {//将原数组从下标 low~middle 中剩余的复制到 temptemp[k++] = arr[i++];}while (j <= high) {//将原数组从下标 middle+1 ~ high 中剩余的复制到 temptemp[k++] = arr[j++];}for (i = 0; i < k; i++) {arr[low + i] = temp[i];}}
}

程序运行结果
在这里插入图片描述

归并排序算法

归并排序算法可看作递归算法, 虽然有的书写成不是递归算法同样实现了

三 步骤

第一步: 一趟归并排序的基本思想是, 在某趟归并中, 设各子文件长度为len(最后一个子文件的长度可能会小于len), 则归并前 R [ 1.. n ] R[1..n] R[1..n] 共有 n l e n \frac{n}{len} lenn 个有序子文件。 调用归并操作对子文件进行归并时, 必须对子文件的个数可能是奇数、最后一个子文件和长度可能小于 l e n len len 这两种特殊情况进行处理:

  1. 若子文件个数为奇数,则最后个子文件无需和其他子文件归并;
  2. 若子文件个数为偶数,则要注意最后一对子文件中后一个子文件的区间上界为 n n n.

第二步: 归并排序的过程需要进行 l o g 2 log_{2} log2 n {n} n 趟。 每一趟排序的操作,就是将两个有序子文件进行归并,
而每一对有序子文件归并时,
记录的比较次数均小于等于记录的移动次数,
记录移动的次数均等于文件中记录的个数
, 即每一趟归并的时间复杂度为 O ( n ) O(n) O(n)
因此归并排序的时间复杂度为 O ( n l o g 2 O(nlog_{2} O(nlog2 n n n ) ) ).
从上述例子可以看出, 空间复杂度为 O ( n ) O(n) O(n)

归并排序是稳定的, 因为在每两个有序子文件 归并时, 若分别在两个有序子文件中出现有相同关键字的记录时, 归并排序算法能够使前一个子文件中同一关键字的记录被先复制,后一子文件中同一关键字的记录后被复制,从而确保它们的相对次序不变。

四 归并算法的优缺点

优点

  1. 适合于大规模数据量,并且要求稳定。
  2. 在基于比较的算法中是最高效率。

缺点
需要数据集长度的辅助空间, 在一定程度上增加了空间复杂度。
如果初始数据几乎填满整个内存,归并排序可能无法工作。

综上,归并算法是应用于大规模数据集最好的排序算法

相关文章:

排序第五篇 归并排序

一 简介 归并排序(Merge Sort) 的基本思想是&#xff1a; 首先将待排序文件看成 n n n 个长度为1的有序子文件&#xff0c; 把这些子文件两两归并&#xff0c; 得到 n 2 \frac{n}{2} 2n​ 个长度为 2 的有序子文件&#xff1b; 然后再把这 n 2 \frac{n}{2} 2n​ 个有序的子…...

【Win】使用PowerShell和Webhooks轻松发送消息至Microsoft Teams

Microsoft Teams是一款由微软开发的团队协作和通讯工具。如果您对这个名字还不太熟悉&#xff0c;那么现在就是一个了解它的好时机。微软将Teams定位为其之前Skype for Business解决方案的继任者&#xff0c;并且它也提供了与其他基于频道的通讯应用程序&#xff08;例如Slack、…...

ESCTF-OSINT赛题WP

这你做不出来?check ESCTF{湖北大学_嘉会园食堂} 这个识图可以发现是 淡水渔人码头 但是 osint 你要发现所有信息 聊天记录说国外 同时 提示给了美国 你综合搜索 美国 渔人码头 在美国旧金山的渔人码头&#xff08;英语&#xff1a;Fisherman’s Wharf&#xff09;是一个著名旅…...

2024蓝桥杯省赛保奖突击班-Day2-前缀和、差分、尺取_笔记_练习题解

3月25日-课堂笔记 前缀和预处理 O ( n ) \mathcal{O}(n) O(n) s[1] a[1]; for(int i 2; i < n; i)s[i] s[i - 1] a[i];利用前缀和查询区间和 O ( 1 ) O(1) O(1) long long calc(int l, int r) {return l 1 ? s[r] : s[r] - s[l - 1]; }差分序列的求法 c[1] a[…...

C++基础之虚函数(十七)

一.什么是多态 多态是在有继承关系的类中&#xff0c;调用同一个指令&#xff08;函数&#xff09;&#xff0c;不同对象会有不同行为。 二.什么是虚函数 概念&#xff1a;首先虚函数是存在于类的成员函数中&#xff0c;通过virtual关键字修饰的成员函数叫虚函数。 性质&am…...

快速入门Kotlin①基本语法

前言 23年底读了一遍“Kotlin官方文档”&#xff0c;官方文档大而全&#xff0c;阅读下来&#xff0c;大有裨益。 此系列文章的目的是记录学习进程&#xff0c;同时&#xff0c;若能让读者迅速掌握重点内容并快速上手&#xff0c;那就再好不过了。 函数 带有两个 Int 参数、…...

【理解指针(四)】

文章目录 一、指针数组二、指针数组来模拟二维数组三、字符指针变量注意&#xff1a; 字符串的例子&#xff08;曾经的一道笔试题&#xff09; 四、数组指针变量1、什么是数组指针变量2、数组指针怎么初始化 五、二维数组传参的本质六、函数指针1、什么是函数指针变量2、函数的…...

Ribbon简介

目录 一 、概念介绍 1、Ribbon是什么 2、认识负载均衡 2.1 服务器端的负载均衡 2.2 客户端的负载均衡 3、Ribbon工作原理 4、Ribbon的主要组件 IClientConfig ServerList ServerListFilter IRule Iping ILoadBalancer ServerListUpdater 5、Ribbon支持…...

【感悟《剑指offer》典型编程题的极练之路】02字符串篇!

​ 个人主页&#xff1a;秋风起&#xff0c;再归来~ 文章所属专栏&#xff1a;《剑指offer》典型编程题的极练之路 ​​​​​​ 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克心守己&#xff0c…...

通过 Docker 实现国产数据库 OpenGauss 开发环境搭建

通过 Docker 实现国产数据库 OpenGauss 开发环境搭建 一 前置准备 2.1 下载镜像 docker pull enmotech/opengauss:5.0.1构建镜像的 Dockerfile&#xff0c;方便后期实现个性化定制&#xff1a; FROM ubuntu:22.04 as builderARG TARGETARCHWORKDIR /warehouseRUN set -eux;…...

【Java】LinkedList模拟实现

目录 整体框架IMyLinkedList接口IndexNotLegalException异常类MyLinkedList类成员变量(节点信息)addFirst(头插)addLast(尾插)在指定位置插入数据判断是否存在移除第一个相等的节点移除所有相等的节点链表的长度打印链表释放回收链表 整体框架 IMyLinkedList接口 这个接口用来…...

ubuntu下mysql常用命令

1. 登录数据库 mysql -u root -p 2.创建数据库 create database 数据库名字 mysql> create database yourdb; Query OK, 1 row affected (0.03 sec)3.显示数据库 show databases; 实操结果如下 mysql> show databases; -------------------- | Database | ---…...

燃气官网安全运行监测系统-阀井燃气监测仪-旭华智能

近年来&#xff0c;燃气爆炸事故频发&#xff0c;造成了重大人员伤亡和财产损失。这也再次为我们敲响警钟&#xff0c;燃气是我们日常生活中不可或缺的能源&#xff0c;但其潜在的危险性也是不容小觑。因此在重要节点加装燃气阀井气体监测仪&#xff0c;并将数据上传到系统平台…...

vue 文件预览(docx、.xlsx、pdf)

1.ifream <iframe src"" ></iframe> 注: src里面是文件地址 2.vue-office 支持vue2和vue3提供docx、.xlsx、pdf多种文档的在线预览方案 2.1安装 #docx文档预览组件 npm install vue-office/docx vue-demi#excel文档预览组件 npm install vue-office…...

云架构(二) 大使模式

Ambassador pattern &#xff08;https://learn.microsoft.com/en-us/azure/architecture/patterns/ambassador&#xff09; 简单描述 创建一个助手服务&#xff0c;这个服务代表消费服务或者应用程序发送网络请求。大使服务可以看做是与客户机同一个位置的进程外代理。 这种…...

.NET Path类库的特殊方法

在.NET中Path类库是非常常用的一个类库&#xff0c;包含很多我们常用的方法&#xff0c;常用的方法这里就不详细说明了&#xff0c;这里记录下几个非常规的方法。 获取随机文件名&#xff1a; //将返回随机的文件名Console.WriteLine(Path.GetRandomFileName()); 获取禁止在路…...

【JVM】JVM常用性能调优参数详细介绍

JVM常用性能调优参数详细介绍 一、何时进行JVM调优二、性能调优三、JVM调优的基本原则四、JVM调优目标五、JVM调优的步骤六、JVM参数七、JVM参数解析及调优八、JVM参数使用手册8.1 内存相关8.2 GC策略相关8.3 GC日志相关8.4 异常相关8.5 问题定位及优化相关九、参考文档一、何时…...

React中的受控组件与非受控组件

受控组件与非受控组件 受控组件 组件(input, select)的状态与state的值绑定&#xff0c;组件的状态全程响应外部数据 class TestComponent extends React.Component {constructor (props) {super(props);this.state { username: lindaidai };}render () {return <input …...

uniapp实现u-datetime-picker时间选择器的默认日期定位,解决default-value不生效问题

uniapp实现u-datetime-picker&#xff0c;设置默认定位日期&#xff0c;解决default-value不生效问题 想实现的效果是点开时间选择器默认显示当前日期&#xff0c;而不是该选择器最早的日期 给选择器添加ref属性&#xff0c;如下&#xff1a; <u-datetime-picker :show&q…...

react native 使用ScrollView实现下拉更新,上拉加载更多

在React Native中&#xff0c;要实现下拉更新和上拉加载更多的功能&#xff0c;你需要自定义ScrollView组件&#xff0c;监听滚动事件并根据滚动的位置来判断何时触发更新和加载更多的操作。以下是一个基本的实现思路&#xff1a; 监听滚动事件&#xff1a;使用ScrollView的on…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...