查看完整的代码,点击这里

不了解归并排序的可以查看百度百科的分析

归并排序的实现

基本实现

package mainimport "fmt"// 合并 [l,r] 两部分数据,mid 左半部分的终点,mid + 1 是右半部分的起点
func merge(arr []int, l int, mid int, r int) {// 因为需要直接修改 arr 数据,这里首先复制 [l,r] 的数据到新的数组中,用于赋值操作 temp := make([]int, r-l+1)for i := l; i <= r; i++ {temp[i-l] = arr[i]}// 指向两部分起点left := lright := mid + 1for i := l; i <= r; i++ {// 左边的点超过中点,说明只剩右边的数据if left > mid {arr[i] = temp[right-l]right++// 右边的数据超过终点,说明只剩左边的数据} else if right > r {arr[i] = temp[left-l]left++// 左边的数据大于右边的数据,选小的数字} else if temp[left - l] > temp[right - l] {arr[i] = temp[right - l]right++} else {arr[i] = temp[left - l]left++}}
}func MergeSort(arr []int, l int, r int) {if l >= r {return}// 递归向下mid := (r + l) / 2MergeSort(arr, l, mid)MergeSort(arr, mid+1, r)// 归并向上merge(arr, l, mid, r)
}func main() {arr := []int{3, 1, 2, 5, 6, 43, 4}MergeSort(arr, 0, len(arr)-1)fmt.Println(arr)
}

优化点

  • 只有左边数据的最大值大于右边数据的最小值时才需要归并

    举例:现在需要归并的左右部分为 [1,3] 和 [4,5],则不需要进行「并」的操作。而 [1,4] 和 [3,5] 则需要进行「并」为 [1,3,4,5]

  • 当二分数据到一定阶段,可以使用插入排序而不是继续向下二分

    虽然复杂度上看 nlogn 始终大于 n^2,但是都忽略了常数项,而归并的常数项大于插入排序,所以当 n 足够小时,插入排序速度更快

    以下是结合优化点的程序更改:

package mainimport "fmt"func merge(arr []int, l int, mid int, r int) {temp := make([]int, r-l+1)for i := l; i <= r; i++ {temp[i-l] = arr[i]}left := lright := mid + 1for i := l; i <= r; i++ {if left > mid {arr[i] = temp[right-l]right++} else if right > r {arr[i] = temp[left-l]left++} else if temp[left - l] > temp[right - l] {arr[i] = temp[right - l]right++} else {arr[i] = temp[left - l]left++}}
}func MergeSort(arr []int, l int, r int) {// 第二步优化,当数据规模足够小的时候,可以使用插入排序if r - l <= 15 {// 对 l,r 的数据执行插入排序for i := l + 1; i <= r; i++ {temp := arr[i]j := ifor ; j > 0 && temp < arr[j-1]; j-- {arr[j] = arr[j-1]}arr[j] = temp}return}mid := (r + l) / 2MergeSort(arr, l, mid)MergeSort(arr, mid+1, r)// 第一步优化,左右两部分已排好序,只有当左边的最大值大于右边的最小值,才需要对这两部分进行merge操作if arr[mid] > arr[mid + 1] {merge(arr, l, mid, r)}
}func main() {arr := []int{3, 1, 2, 5, 6, 43, 4}MergeSort(arr, 0, len(arr)-1)fmt.Println(arr)
}

归并排序的 Go 语言实现和优化相关推荐

  1. Rust和C / C ++的跨语言链接时间优化LTO

    Rust和C / C ++的跨语言链接时间优化LTO 链接时间优化(LTO)是LLVM实施整个程序优化的方法.跨语言LTO是Rust编译器中的一项新功能,使LLVM的链接时间优化可以在混合的C / C ...

  2. 归并排序及C语言实现

    排序系列之(1)归并排序及C语言实现 有很多算法在结构上是递归的:为了解决一个给定的问题,算法需要一次或多次递归的调用其本身来解决相关的问题.这些算法通常采用分治策略:将原问题划分成n个规模较小而结构 ...

  3. 对归并排序进行c语言编程实现,归并排序及C语言实现

    排序系列之(1)归并排序及C语言实现 有很多算法在结构上是递归的:为了解决一个给定的问题,算法需要一次或多次递归的调用其本身来解决相关的问题.这些算法通常采用分治策略:将原问题划分成n个规模较小而结构 ...

  4. c语言学习进阶-C语言程序性能优化

    标题C语言程序性能优化 (1)进一步提升程序的计算能力.使之能计算任意实数的任意次方的输出结果,我们 将计算的次方数也放在命令行参数中,作为第3 个命令行参数,例如:d:>p.exe input ...

  5. c 语言编写脚本优化,两周自制脚本语言-第11天 优化变量读写性能

    第11天 优化变量读写性能 以变量值的读写为例,向读者介绍基于这种理念的语言处理器性能优化方式. 11.1 通过简单数组来实现环境 假如函数包含局部变量x与y,程序可以事先将x设为数组的第0个元素,将 ...

  6. 易语言误报优化助手 v1.5

    名称:易语言误报优化助手 v1.5 版本:1.5 软件大小:1.17 MB 软件语言:简体中文 软件授权:共享版 应用平台:Win7/Win8/Win2003/WinXP 易语言误报优化助手是为易友定 ...

  7. 【排序算法】归并排序(C语言)

    [排序算法]-- 归并排序(C语言) 目录 一.归并排序的原理 二.两个有序数组排序和合并 1. 原地排序 2. 创建临时空间 二.递归实现 三.非递归实现 1. 实现思路 2. 数组边界问题 3. ...

  8. C语言的冒泡排序优化及鸡尾酒排序问题分解知识点

    关于C语言的冒泡排序优化及鸡尾酒排序 /*对于冒泡排序的公式分享,其实只要把公式背下来就行,没有什么大碍,本人新手,大一新生, 对于排序的算法,我第一个接触的排序算法就是冒泡排序,下面我就简单给一个例 ...

  9. C语言扫雷(优化)超详细

    ​ 本期主要介绍如何用C语言实现扫雷优化版本 文章目录 一.扫雷游戏介绍 二.test.c的实现 2.1扫雷游戏的运行 2.2 程序的大体思路 2.3 很妙的想法 三.game.c文件的实现 3 .1 ...

最新文章

  1. php中time()和mktime()方法的区别
  2. linux下如何实现mysql数据库每天自动备份定时备份
  3. python面试经典题_16道Python经典面试题及答案
  4. iOS程序启动原理(上)
  5. PB-treeview基本属性事件函数
  6. Go defer实现原理剖析
  7. ubuntu或者fedora下编译淘宝tair key-value-db的开源内存数据库
  8. python后端开发书籍_后端书籍推荐
  9. RAID5中的“左、右循环”与“同步、异步”(2)
  10. hello bokeyuan
  11. 网站服务器检测工具,服务器网络监测工具
  12. Pascal VOC 2007和2012数据集下载地址(不需国外,速度依旧让你感动)
  13. 嵌入式系统一般用c语言编写,ARM嵌入式系统C语言编程
  14. Theano与其他深度学习框架的比较
  15. linux内核学习(5)山重水复疑无路*
  16. 为大家准备一份数据分析师简历的清单
  17. C语言利用数组输出26个小写字母
  18. 第15节-热区Hot Spots | 剑雨Axure RP9系列【基础】
  19. 【云原生概念和技术】1.1 云原生的概述
  20. linux 同一个交换机 不通,同一个交换机 局域网内 内网IP ping不通为什么 没关闭windows防火墙...

热门文章

  1. 结构体和typedef
  2. oracle10 exp imp 中文乱码
  3. 数据结构基础(21) --DFS与BFS
  4. 在Linux和Windows下删除文件夹中包含的.svn文件的方法
  5. 【Android必备】与其他碎片进行通信(10)
  6. shell的嵌入命令大全
  7. 一文读懂 CNN、DNN、RNN 内部网络结构区别
  8. linux 批量重命名文件
  9. 使用TinySpider实战抓取自己博客中的内容
  10. 为什么c程序里一定要写main函数