经典排序三剑客: 归并,堆排,快排。

      今天,图解归并,一步步带你手撕代码~

      归并排序,是采用"分而治之"思想的一个典型应用。

      分治法精髓:

      1. --- 将问题分解成若干个规模更小的问题

      2. --- 将这些规模更小的问题逐个击破

      3. --- 将已解决的子问题合并,最终得到"母"问题的解

      知道了归并思想,如图,归并排序流程我们也能想到:

      1.将待排序数组分解两个子序列,先让让左右两个子序列有序,然后再用两个有序数组合并的算法合并。那么怎么让左右子序列有序呢?

      

      2.我们发现左右子序列还可以继续分解,左右子序列也可以通过自身的左右子序列排序后归并得到

      3.继续分解,分解到最小规模,也就是每个部分只有一个元素,我们发现每部分已经有序了

      4.分治完,如图,开始用两个有序数组合并的算法合并,我们会发现这是一个递归过程,子问题的合并解就是该子问题"母问题"的解

 

  

      归并流程我们可以用递归实现,接下来要图解合并两个有序数组的算法 :

        

        C代码实现:

#include<stdlib.h>
#include<stdio.h> //归并两个有序数组
void Merge(int* a, int left, int mid, int right,int* tmp)
{ int begin1 = left, end1 = mid;
int begin2 = mid+, end2 = right;
int index = left; //比较排序(双指针)
while (begin1<=end1 && begin2<=right)
{
if (a[begin1] <= a[begin2])
{
tmp[index++] = a[begin1++];
}
else
{
tmp[index++] = a[begin2++];
}
}
//若剩余数组,按序插入
while (begin1 <= end1)
tmp[index++] = a[begin1++]; while (begin2 <= end2)
tmp[index++] = a[begin2++];
//拷贝到原数组
index = left;
while (left <= right)
{
a[left++] = tmp[index++];
}
} //分解成最小子问题,回溯归并
void Sort(int *a, int left, int right,int* tmp)
{
//递归终止条件 : 只剩一个元素
if (left >= right)
return; int mid = left + (right-left)/;
Sort(a, left, mid,tmp);
Sort(a, mid+, right,tmp);
Merge(a, left, mid, right,tmp);
} //归并排序
void MergeSort(int *a, int n)
{
int* tmp = (int *)malloc(sizeof(int)*n);
Sort(a, , n - , tmp);
free(tmp);
}

 时间复杂度:O(nlogn)

    空间复杂度:O(N),归并排序需要一个与原数组相同长度的数组做辅助来排序

稳定性: 稳定, 不管顺序如何,都要分解成最小子问题进行归并。

     

DS 图解归并排序的更多相关文章

  1. DS 图解快排

    快速排序是交换排序,是冒泡排序的改进版. 快排过程: 1.选定一个分界值     2.分成三个部分(小于分界部分,分界值,大于分界值部分)                       3.对于分开的两 ...

  2. DS 图解堆排

    堆排其实就是选择排序,只不过用了完全二叉树特性. 堆排思想 : 利用完全二叉树特性建堆和重复选择调整来得到有序数组. 完全二叉树有什么特性呢? 节点左对齐 ---> 层序遍历不会出现空,可以用数 ...

  3. java泛型中使用的排序算法——归并排序及分析

    一.引言 我们知道,java中泛型排序使用归并排序或TimSort.归并排序以O(NlogN)最坏时间运行,下面我们分析归并排序过程及分析证明时间复杂度:也会简述为什么java选择归并排序作为泛型的排 ...

  4. 【高级排序算法】1、归并排序法 - Merge Sort

    归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...

  5. java知识树

    https://blog.csdn.net/aitaozi11/article/details/79652943 (学习Java的9张思维导图) 文章目录 针对技术栈学习 1. java基础 1.1 ...

  6. 10大排序算法——Java实现

    算法与实现 选择排序 算法思想 从数组中选择最小元素,将它与数组的第一个元素交换位置.再从数组剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置.不断进行这样的操作,直到将整个数组排序. 动 ...

  7. [图解算法] 归并排序MergeSort——<递归与分治策略>

    #include"iostream.h" void Merge(int c[],int d[],int l,int m,int r){ ,k=l; while((i<=m)& ...

  8. 【DS】排序算法之归并排序(Merge Sort)

    一.算法思想 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作.其归并思想如下: 1)申请空间,使其大小为两个已经 ...

  9. java归并排序,单线程vs多线程

    一.什么是归并排序 归并排序又称合并排序,它是成功应用分治技术的一个完美例子.对于一个需要排序的数组A[0..n-1],归并排序把它一分为二:A[0..n/2-1]和A[n/2..n-1],并对每个子 ...

随机推荐

  1. 指针的运算符&、*

    int y=0; int* yptr=&y; •互相反作用 •*&yptr -> * (&yptr) -> * (yptr的地址)-> 得到那个地址上的变量 ...

  2. [JLOI 2015]骗我呢

    传送门 Description 求给\(n*m\)的矩阵填数的方案数 满足: \[ 1\leq x_{i,j}\leq m \] \[ x_{i,j}<x_{i,j+1} \] \[ x_{i, ...

  3. Apache ranger整合hive报错记录

    版本信息如下: hadoop2.9.2 hive 2.x ranger 最新版2.1.0 在hive端部署完ranger 插件以后,在使用beeline连接查询数据库时报错,报错信息如下: verbo ...

  4. ICEM-三棱锥的一种画法

    原视频下载地址:https://pan.baidu.com/s/1c4BAqy 密码: nqb4

  5. 牛顿插值法(c++)【转载】

    摘自<c++和面向对象数值计算>,代码简洁明快,采用模板函数,通用性增强,牛顿差分合理利用存储空间,采用Horner算法(又称秦九韶算法)提高精度,减少时间复杂度,高!确实是高!对其中代码 ...

  6. gdal 根据条件选择数据

  7. java查看线程的堆栈信息

    通过使用jps 命令获取需要监控的进程的pid,然后使用jstack pid 命令查看线程的堆栈信息. 通过jstack 命令可以获取当前进程的所有线程信息. 每个线程堆中信息中,都可以查看到线程ID ...

  8. merge同时包含增、改、删

    我们都知道oracle merge可以用来增和改,很少用它来删除.但是有时候我们仍然需要该特性,以提高性能,典型的场景就是将业务库逻辑删除的记录同步到查询库的时候,做真正的物理删除,这个时候merge ...

  9. ThinkPHP 控制器不存在问题排查

    新手经常会遇到这种问题,提示控制器找不到,一般的情况如下: 1. 命名空间地址错误 检查你的控制器命名空间是否正确

  10. asp.net core 获取appsettings.json里的配置

    public GoodsController(IConfiguration configuration) { Configuration = configuration; UpFileDir = Co ...