序言

二路归并排序是一种效率极高的递归排序,将数组A化为有序数组时间复杂度为O(nlogn)。

思想

二路归并排序分为拆分数组以及合并两个操作。

切分(自上而下)时间复杂度2*T(n/2)

每次从数组A中间切分,将数组分为[low,mid]以及[mid+1,high]两段,直至不可再分(low不小于high)即最终分成最下层一个一个的数组。当然在代码中不会让他真的变成一个一个数组!用下标圈定范围即可。

合并(自下而上)时间复杂度T(n)

将两段各自有序的数组合并成一个有序数组,并逐步向上合并,最终得到一个有序数组。

下面举例分析如何进行合并操作,需要三个指针,我设为i,j,k

  1. 比较下面两个数组指针(i,j)所指位置的数值
  2. 将较小的放入上面的有序数组里,例如第一次比较17<28,故将17放入上面有序数组中的第一个位置。此时i++,k++即i,k向后移动一位
  3. 直至下面两个数组其中之一遍历完成,该例子为【17,24】遍历完成,而【28,40】并未遍历完成
  4. 最终将未遍历完的数组剩下部分复制到上面的那个有序数组里

辅助数组B的作用

在合并操作中,先将此次需要合并的A数组全部放入B中,即i,j所指向的数组B,没错,他俩实际上在代码中就是一个数组只不过人为的在中间分开了,分为[low,mid],[mid+1,high]两段而已。
再经历上述合并步骤,将这两段数组合并到A数组的原位置中[low,high]中。
即i,j指向的是B数组的元素,而k指向的是A数组的元素

代码

#include<iostream>
using namespace std;#define n 16//辅助数组--->空间复杂度O(n)
int* B = (int*)malloc((n + 1) * sizeof(int));//合并
void merge(int A[], int low, int mid, int high) {//将A复制到Bfor (int k = low; k <= high; k++) {B[k] = A[k];}int i, j, k;//循环结束条件需要满足左右数组其中之一遍历结束for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++) {if (B[i] <= B[j])A[k] = B[i++];elseA[k] = B[j++];}//若左数组未遍历结束while (i <= mid)A[k++] = B[i++];//若右半数组未遍历结束while (j <= high)A[k++] = B[j++];
}//二路归并排序
void mergeSort(int A[], int low, int high) {if (low < high) {int mid = (low + high) / 2;//左半数组--->T(n/2)mergeSort(A, low, mid);//右半数组--->T(n/2)mergeSort(A, mid + 1, high);//合并--->T(n)merge(A, low,mid, high);}
}
int main() {int A[16] = {24,17,40,28,13,14,22,32,40,21,48,4,47,8,37,18};mergeSort(A, 0, 15);for(int i  =0;i<n;i++)cout << A[i]<<" ";return 0;
}

时间复杂度分析

  1. 首先,每次将数组分为左半数组和右半数组mergeSort时间复杂度均为T(n/2)
  2. 合并操作merge空间复杂度为T(n)
  3. 故实际时间复杂度公式为

一、递归树法


每一层都是上一层的一半,共有logn层,而每一层都有一次时间复杂度为O(n)的合并操作,故时间复杂度为O(nlogn)

二、主定理法(推荐)


该式中a = 2 , b =2 , k = 1 满足第二个式子 即时间复杂度为o(nlogn)

------------思想以及图片摘取自北航童咏昕教授算法公开课,代码摘取自王道考研数据结构

二路归并排序及时间复杂度分析相关推荐

  1. 关于快速排序和归并排序的时间复杂度分析

    目录 一.快排时间复杂度分析 二.归并排序时间复杂度分析 三.写在最后 一.快排时间复杂度分析 快速排序的时间复杂度在O(nlogn)~ O(n^2)之间,下面我分别分析这两种情况: (一)快速排序的 ...

  2. 排序算法-归并排序的时间复杂度分析

    归并排序,其实就是递归+合并. 归并排序将数组取中间分为两部分,两个子数组分别各自再从中间分为两个子数组,一直分下去直到不能再分.分完之后,再按照子数组大小合并为为一个有序数组,然后层层向上合并,直到 ...

  3. 归并排序 快速排序 时间复杂度分析 (基本递归时间复杂度分析)

    归并排序 归并排序:利用分治的思想,先排左边一半,再排右边一半,最后再将两边有序的合并起来. 时间复杂度: 用T(n)T(n)T(n)表示排大小为nnn的数组的时间:T(n)=2T(n/2)+nT(1 ...

  4. 归并排序执行次数_归并排序过程、时间复杂度分析及改进

    前言 上一篇文章,介绍过第一种基于分治策略的排序算法--快速排序.接下来我们来讨论另一种基于分治策略的排序算法,归并排序.归并排序也被认为是一种时间复杂度最优的算法,我们还是按照基本过程,代码,最坏时 ...

  5. 希尔排序、快速排序、归并排序的实现分析以及时间复杂度

    高级排序 希尔排序 快速排序 归并排序 希尔排序 希尔排序是插入排序的一种,又称"缩小增量排序",是插入排序算法的一种更高效的改进版本. 我在另一篇文章中说插入排序的时候,会有一个 ...

  6. 快速排序归并排序—时间复杂度分析

    引言: 大家好,我是小星星,今天要梳理的知识点是--快速排序和归并排序时间复杂度分析. 目录 一.快排时间复杂度分析 二.归并排序时间复杂度分析 三.写在最后 一.快排时间复杂度分析 快速排序的时间复 ...

  7. 排序算法-归并排序的实现与时间复杂度分析

    归并排序 归并排序是分而治之的排序算法. 划分步骤很简单:将当前数组分成两半(如果N是偶数,则将其完全平等,或者如果N是奇数,则一边稍大于一个元素),然后递归地对这两半进行排序. 递归写法 归并排序递 ...

  8. 二路归并排序简介及其并行化

    1.归并排序简介 1.1算法思想 归并排序属于比较类非线性时间排序,比较类排序中性能最佳,应用较为广泛. 归并排序是分治法(Divide and Conquer)的一个典型的应用.将已有序的子序列合并 ...

  9. 数据结构——二路归并排序和基数排序

    二路归并排序 算法原理 假设该数组为q,左边界为 l,右边界为 r,并设置临时数组tmp. 采用分治思想: 第一步:确定分界点: mid = l + r >>1. 第二步:递归划分左右两段 ...

最新文章

  1. vsftp认证之pam_mysql
  2. 漫长的数据中心绿化之路到底该如何走www.shzhenai.com
  3. 在ListView的顶部和底部加入其他View
  4. centos smb配置与win7共享
  5. 【HDU - 1285】确定比赛名次 (拓扑排序)
  6. ERROR: Could not install packages due to an OSError: [Errno 28] 设备上没有空间
  7. Windows环境中jdk的下载、安装与配置
  8. C语言学习及项目开发所遇问题总集(一)---Mr.Zhang
  9. 说道说道 ios 图片尺寸的问题
  10. 标准Android按钮具有不同的颜色
  11. [codeup 5038] 找零钱
  12. Python实战项目—金融量化分析(数据的简单预处理)
  13. 香农编码的MATLAB实现
  14. 资源 | 11个免费矢量免抠素材网站
  15. MHL中的packedpixel概念
  16. 2014 你好,再见
  17. Python的运行环境
  18. 完美破解下载神器IDM
  19. Maven创建聚合项目
  20. 个人博客开发之blog-api项目统一结果集api封装

热门文章

  1. 成功解决:不允许有匹配 “[xX][mM][lL]“ 的处理指令目标。
  2. linux生成ssl证书
  3. Java 程序员不得不会的 124 道面试题(含答案)
  4. Android多媒体框架(3)—— libstagefright中MediaCodec源码分析
  5. Portraiture Mac(PS磨皮滤镜插件) v3.5.1已注册版
  6. 养颜有妙--招-喝水可祛痘、退烧、养胃、助眠
  7. php实现微信小程序获取用户openid,昵称和头像方法
  8. QT 5.3.2 + VC2012 中文乱码 完美解决方案
  9. 3D人体姿态识别数据集
  10. allenNLP入门记录