[Go版]算法通关村第十关黄金——归并排序

news2024/11/14 15:13:54

目录

归并排序(mergeSort)

在这里插入图片描述

思路分析:二分分割 + 合并两个数组 + 递归

  1. 分割(Divide):将待排序的数组分割成两个子数组,将问题分解为更小的子问题。通常将数组分割成相等大小的两半,直到无法再分割(即数组中只剩下一个或零个元素)。
  2. 解决(Conquer):对每个子数组递归地进行排序。当子数组长度变得很小(通常为1)时,直接认为它们已经有序。
  3. 合并(Merge):将两个已排序的子数组合并为一个单一的、有序的数组。在合并过程中,通过逐一比较两个子数组中的元素,按照大小顺序将它们合并到一个新的数组中。

遍历时处理元素的过程图:

在这里插入图片描述

递归遍历时栈内的数据图:

在这里插入图片描述

复杂度:时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)、空间复杂度 O ( n ) O(n) O(n)

  • 时间复杂度:归并排序的时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn),其中 n 是数组的长度。归并排序将数组不断分割为两半,然后在合并的过程中将各个子数组进行合并操作。因为每次都是将两个有序的子数组合并,所以合并的时间复杂度是线性的,合并的次数是 O ( l o g n ) O(log n) O(logn)。因此,总体的时间复杂度是 O ( n l o g n ) O(n log n) O(nlogn)
  • 空间复杂度:在合并操作中使用了临时数组 tmp 来存储合并后的结果,其大小与原数组的大小相同。因此,空间复杂度是 O(n),其中 n 是数组的长度。

Go代码

func sortArray(nums []int) []int {
    length := len(nums)
    if length == 0 || length == 1 {
        return nums
    }
    // 初始化时创建tmp,然后在每次合并时复用这个数组,可避免在每次递归调用时创建和释放临时数组,从而减少空间的创建和释放次数
    tmp := make([]int, length)
    sortArr(nums, 0, length-1, tmp)
    return nums
}

func sortArr(nums []int, left int, right int, tmp []int) {
    if left>=right {
        return
    }
    mid := (right-left)>>1+left
    // 拆分数组
    sortArr(nums, left, mid, tmp)
    sortArr(nums, mid+1, right, tmp)
    i,j := left, mid+1
    x := 0
    // 合并到tmp
    for ;i<=mid&&j<=right; x++ {
        if nums[i] < nums[j] {
            tmp[x] = nums[i]
            i++
        } else {
            tmp[x] = nums[j]
            j++
        }
    }
    for ;i<=mid; x,i=x+1,i+1 {
        tmp[x] = nums[i]
    }
    for ;j<=right; x,j=x+1,j+1 {
        tmp[x] = nums[j]
    }
    // 从tmp赋值到nums
    for i:=0; i<=right-left; i++ {
        nums[i+left] = tmp[i]
    }
}

比较:归并排序 和 快速排序

快速排序:

平均时间复杂度:O(n log n)
最坏情况时间复杂度:O(n^2)(当划分不均匀时,例如已经有序的数据)
最好情况时间复杂度:O(n log n)(当每次划分都能平分数组)
不稳定排序:相等元素的相对顺序可能被改变
需要较少的额外内存

归并排序:

平均时间复杂度:O(n log n)
最坏情况时间复杂度:O(n log n)
最好情况时间复杂度:O(n log n)
稳定排序:相等元素的相对顺序不会改变
需要较多的额外内存(用于合并操作)

在实际应用中,快速排序通常比归并排序更快,因为它的常数因子较小,而且在一些情况下,归并排序的额外内存消耗可能限制了它的效率。然而,需要注意的是,快速排序的性能高度依赖于数据的分布和选取的枢轴(pivot)元素。如果选择的枢轴不好,快速排序的性能可能下降到最坏情况。

归并排序的性能相对稳定,适用于各种数据分布情况,并且在一些对内存消耗有限制的情况下也很有用。

综上所述,虽然快速排序通常更快,但要根据具体情况选择合适的排序算法,以满足不同的性能和内存需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/891579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

innodb的锁

一致性锁定读和一致性非锁定读 Read Committed和Repetable Read级别下采用MVCC 实现非锁定读 但在一些情况下&#xff0c;要使用加锁来保障数据的逻辑一致性 自增列 锁的算法 唯一值 MySQL 中关于gap lock / next-key lock 的一个问题_呜呜呜啦啦啦的博客-CSDN博客 RR可以通过…

为什么一些程序员很傲慢?懂点编程了不起吗?

Perl 语言之父 Larry Wall 说过&#xff0c;好的程序员有 3 种美德&#xff1a;懒惰、急躁和傲慢&#xff08;Laziness, Impatience and hubris&#xff09;。 在日常工作中&#xff0c;程序员的傲慢可以说是被吐槽的最多的&#xff0c;之前还有人特地开了帖子&#xff0c;发…

九耶丨阁瑞钛伦特-HashCode是什么

HashCode是一种用于快速查找和比较对象的方法。它是一个整数值&#xff0c;由对象的内容计算得出。HashCode通常用于数据结构中的散列函数&#xff0c;如哈希表、散列表等。 HashCode的作用有以下几点&#xff1a; 在哈希表中快速查找对象&#xff1a;哈希表根据对象的HashCod…

SQL Server数据库无法连接

问题如下&#xff1a; 原因&#xff1a;sql server服务器未开启 解决方法&#xff1a;以管理员身份打开cmd&#xff0c;输入&#xff1a;net start mssqlserver。

[Go版]算法通关村第十二关白银——字符串经典基础面试题

目录 反转专题题目&#xff1a;反转字符串思路分析&#xff1a;左右双指针 对向交换复杂度&#xff1a;时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( 1 ) O(1) O(1)Go代码 题目&#xff1a;反转字符串 II思路分析&#xff1a;K个一组反转思想&#xff08;找到每组的首尾索引…

实在没货,简历(软件测试)咋写?

简历咋写&#xff0c;这是很多没有【软件测试实际工作经验】的同学们非常头疼的事情。 简历咋写&#xff1f;首先你要知道简历的作用。 简历的作用是啥呢&#xff1f;一句话就是&#xff1a;让HR小姐姐约你。 如何让HR看你一眼&#xff0c;便相中你的简历&#xff0c;实现在众…

AcrelEMS-IDC数据中心综合能效管理系统解决方案-安科瑞黄安南

1 概述 安科瑞电气紧跟数据中心发展形式&#xff0c;推出AcrelEMS-IDC数据中心综合能效管理解决方案&#xff0c;包含有电力监控、动环监控、消防监控、能耗统计分析、智能照明控制以及新能源监测几个子系统。集成了变配电监测、电源备自投、电气接点测温、智能照明控制、电能…

vue 实现图片懒加载

一&#xff1a;懒加载的目的 有些页面可能展示的是大量的图片&#xff0c;如果我们一次性加载所有图片就会浪费性能&#xff0c;影响用户体验&#xff0c;所以我们就会懒加载这些图片。即可视区域之外的图片不加载&#xff0c;随着页面的滚动&#xff0c;图片进入可视区域&…

小程序swiper一个轮播显示一个半内容且实现无缝滚动

效果图&#xff1a; wxml&#xff08;无缝滚动&#xff1a;circular"true"&#xff09;&#xff1a; <!--components/tool_version/tool_version.wxml--> <view class"tool-version"><swiper class"tool-version-swiper" circul…

基于IMX6ULLmini的linux裸机开发系列二:使用C语言和SDK点亮LED

引入sdk头文件 sudo chown -R gec /opt 用这条命令给gec赋权限&#xff0c;否则访问权限不够&#xff0c;无法读取&#xff0c;如下图成功 目的&#xff1a;解决寄存器地址难查难设置 devices/MCIMX6Y2/MCIMX6Y2.h 记录外设寄存器及其相关操作 devices/MCIMX6Y2/drivers/fsl_…

分班情况通知如何下发?使用这个技术源一键搞定

在下发分班情况通知之前&#xff0c;我们需要制作好分班查询页面&#xff0c;我们先来看看利用易查分快速制作分班查询页面的教程&#xff0c;后面会分享具体的【分班情况通知范文】【分班情况通知下发方式】&#xff01; 分班查询页面制作教程 在制作分班查询系统前&#xff…

《Go 语言第一课》课程学习笔记(四)

构建模式&#xff1a;Go Module 的 6 类常规操作 为当前 module 添加一个依赖 我们如何为一个 Go Module 添加一个新的依赖包呢&#xff1f; 如果我们要为项目增加一个新依赖&#xff1a;github.com/google/uuid&#xff0c;我们首先会更新源码&#xff1a;package mainimpor…

Docker 三要素

文章目录 Docker 简介Docker客户端Docker服务器Docker 镜像Docker 容器 Docker 简介 学习完容器的相关概念&#xff0c;开始学习docker的核心组件分别是Docker客户端、Docker服务器、Docker镜像、Docker容器、仓库。 学习之前&#xff0c;我们先思考一个问题&#xff0c;目前…

如何关闭“若要接收后续google chrome更新,您需使用windows10或更高版本”

Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Software\Policies\Google\Chrome] "SuppressUnsupportedOSWarning"dword:00000001 如何关闭“若要接收后续 google chrome 更新,您需使用 windows 10 或更高版本” - 知乎

影视公司技术流程设计之服务器搭建

在影视公司&#xff0c;硬件的投入占相当大的比例&#xff0c; 大到存储&#xff0c; 服务器&#xff0c;工作站&#xff0c; 小到主机CPU&#xff0c;内存&#xff0c;显卡&#xff0c;手绘板。 而存储又是硬件上的大头&#xff0c;一套合理的存储解决方案&#xff0c;优为关键…

render和h函数的使用

// 如果没有配置项&#xff0c;则可以省略不写 {}h("div", [h(h-tooltip, // 在tooltip中进行改造// ----- h-tooltip 的配置项 -----Start{props: {placement: "top-start",// content: 提示内容,transfer: true},style: {overflow: hidden,text-overflow…

信安通用基础知识

文章目录 密码学经典误区PGP优良保密协议信安经典其它安全手段XSS与CSRF cross site request forgeryCSRF的利用逻辑CSRF示例CSRF防范检查Referer字段添加校验token XSS cross site scripting common weakness enumeration常见密码api误用&#xff08;摘自毕设参考文献&#xf…

Java面试题目汇总

一、面向对象的三个基本特征 2、方法重载和方法重写的概念和区别 3、接口和内部类、抽象类的特性 4、文件读写的基本类 **5、串行化的注意事项以及如何实现串行化 6、线程的基本概念、线程的基本状态以及状态之间的关系 7、线程的同步、如何实现线程的同步 8、几种常用的数据结…

如何仿写简易tomcat 实现思路+代码详细讲解

仿写之前&#xff0c;我们要搞清楚都要用到哪些技术 自定义注解&#xff0c;比如Tomcat使用的是Servlet&#xff0c;我们可以定义一个自己的MyServlet构造请求体和返回体&#xff0c;比如tomcat使用HttpRequest&#xff0c;我们可以自己定义myHttpRequestjava去遍历一个指定目…

华为网络篇 单区域OSPF-32

难度1复杂度1 目录 一、相关原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、相关原理 OSPF&#xff08;Open Shortest Path First&#xff09;是一种链路状态路由协议&#xff0c;它是由IETF的OSPF工作组开发的公有协议&#xff0c;所有的厂商都可以使用它。相比静…