归并排序解释

归并排序 Merge Sort 是典型的分治法的应用,其算法步骤完全遵循分治模式。

分治法思想

分治法 思想: 将原问题分解为几个规模较小但又保持原问题性质子问题递归求解这些子问题,然后再合并这些子问题的解,最终得到原问题的解。

分治模式每层递归步骤

1、分解原问题为若干个子问题;

2、解决子问题。递归求解子问题,当子问题规模足够小时,可以直接求解;

3、合并这些子问题的解构成原问题的解。

归并排序的分治模式

1、分解未排序 n 个元素的序列成 各有 n/2 个元素的连续子序列;

2、递归排序两个连续子序列;

3、合并两个已排序的连续子序列构成整个完成排序的序列。


归并排序递归树

我们以序列 [7, 4, 8, 1, 3, 5, 6, 2] 为例构建一个归并排序的递归树

上半部分递归树为将当前长度为 n 的序列拆分成长度为 n/2 的子序列,下半部分递归树为合并已经排序的子序列。


时间复杂度

假设时间复杂度为 T(n),在递归解决当前两个规模为 n/2 的子问题时,我们需要消耗 2T(n/2)* 的时间。

在合并过程中,对于一个具有 n 个元素的序列,我们需要消耗O(n)的时间。

故时间复杂度如下


归并排序核心代码

void Merge(int a[], int left, int mid, int right){
int temp[right - left + 1]; //临时数组用于存储排序时的数
int i = left; //分成两块 i指向左边的数字 j指向右边的数字
int j = mid + 1;
int k = 0; //k用于存储数字到临时数组 while( i <= mid && j <= right ){
if(a[i] < a[j]) //永远都是 i 和 j 指向的数进行比较
temp[k++] = a[i++]; //谁小,谁就先放到临时数组中
else
temp[k++] = a[j++];
} while( i <= mid ) //如果左边还有数没放上去,就依次放上去
temp[k++] = a[i++];
while( j <= right ) //如果是右边还有同上
temp[k++] = a[j++]; for(int m = left, n = 0; m <= right; m++, n++)//读取临时数组中的数
a[m] = temp[n];
} void Merge_Sort(int a[], int left, int right){
if( left == right )
return; int mid = (left + right)/2;
//递归拆分成较小规模子序列排序
Merge_Sort(a, left, mid);
Merge_Sort(a, mid + 1, right);
Merge(a, left, mid, right); //合并较小规模问题解
}

完整程序源代码

#include<iostream>
#include<ctime>
using namespace std; void Merge(int a[], int left, int mid, int right){
int temp[right - left + 1]; //临时数组用于存储排序时的数
int i = left; //分成两块 i指向左边的数字 j指向右边的数字
int j = mid + 1;
int k = 0; //k用于存储数字到临时数组 while( i <= mid && j <= right ){
if(a[i] < a[j]) //永远都是 i 和 j 指向的数进行比较
temp[k++] = a[i++]; //谁小,谁就先放到临时数组中
else
temp[k++] = a[j++];
} while( i <= mid ) //如果左边还有数没放上去,就依次放上去
temp[k++] = a[i++];
while( j <= right ) //如果是右边还有同上
temp[k++] = a[j++]; for(int m = left, n = 0; m <= right; m++, n++)//读取临时数组中的数
a[m] = temp[n];
} void Merge_Sort(int a[], int left, int right){
if( left == right )
return; int mid = (left + right)/2;
//递归拆分成较小规模子序列排序
Merge_Sort(a, left, mid);
Merge_Sort(a, mid + 1, right);
Merge(a, left, mid, right); //合并较小规模问题解
} void Show(int a[], int n){
for(int i = 0; i < n; i++)
cout<<a[i]<<" ";
cout<<endl;
} main(){
int a[50];
srand((int)time(0));
for(int i = 0; i < 50; i++)
a[i] = rand() % 100 + 1;
Show(a, 50); Merge_Sort(a, 0, 50); cout<<endl<<endl;
Show(a, 50);
}

程序运行结果图

[排序算法] 归并排序 (C++)的更多相关文章

  1. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  2. 数据结构和算法(Golang实现)(23)排序算法-归并排序

    归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...

  3. 使用 js 实现十大排序算法: 归并排序

    使用 js 实现十大排序算法: 归并排序 归并排序 refs js 十大排序算法 All In One https://www.cnblogs.com/xgqfrms/p/13947122.html ...

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

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

  5. js 实现排序算法 -- 归并排序(Merge Sort)

    原文: 十大经典排序算法(动图演示) 归并排序 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得 ...

  6. javascript排序算法-归并排序

    归并排序 概念:归并排序是一种分治算法.其思想是将原始数组切分成较小的数组,直到每个小数组只有一个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组. 时间复杂度: O(nlogn) ...

  7. 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1.  向上归并排序的时候,需要一个暂存数组用来排序, 2.  将 ...

  8. 排序算法-归并排序(Java)

    package com.rao.sort; import java.util.Arrays; /** * @author Srao * @className MergeSort * @date 201 ...

  9. 疯子的算法总结(六) 复杂排序算法 ① 归并排序 merge_sort()

    归并排序采取了分治的思想,每次分别排左半边和右半边,不断递归调用自己,直到只有一个元素递归结束,开始回溯,调用merge函数,合并两个有序序列,再合并的时候每次给末尾追上一个最大int这样就不怕最后一 ...

  10. JavaScript排序算法——归并排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. dp-LIS LCS 模型

    最长上升子序列问题: https://www.cnblogs.com/sxq-study/p/12303589.html 一:两遍LIS问题 1:题目: 怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为 ...

  2. SQL注入篇——sqli-labs各关卡方法介绍|1-65

    主要是记下来了每关通过可以采用的注入方式,可能部分关卡的通关方式写的不全面,欢迎指出,具体的获取数据库信息请手动操作一下. 环境初始界面如下: sql注入流程语句: order by 3--+ #判断 ...

  3. Mysqldump 的 的 6 大使用场景的导出命令

    Mysqldump 选项解析 场景描述 1. 导出 db1.db2 两个数据库的所有数据. mysqldump -uroot -p -P8635 -h192.168.0.199 --hex-blob ...

  4. Kubernetes 部署 Nacos 1.4 集群

    文章转载自:http://www.mydlq.club/article/104/ 系统环境: Nacos 版本:1.4.1 Mysql 版本:8.0.19 Kubernetes 版本:1.20.1 一 ...

  5. 使用kuboard部署某一个应用的pod分布于不同的主机上

    情况介绍 1.k8s集群有8个节点,3个节点是master,分别是master1,master2,master3. 5个worker节点,分别是worker1,worke2,worke3,worker ...

  6. Elasticsearch中的一些重要概念:cluster, node, index, document, shards及replica

    首先,我们来看下一下如下的这个图: Cluster Cluster也就是集群的意思.Elasticsearch集群由一个或多个节点组成,可通过其集群名称进行标识.通常这个Cluster 的名字是可以在 ...

  7. oracle中的行转列,列转行

    行转列:源表: 方法1:case when select y,sum(case when q=1 then amt end) q1,sum(case when q=2 then amt end) q2 ...

  8. JVM、JDK、JRE你分的清吗

    JVM.JDK.JRE你分的清吗 前言 在我们学习Java的时候,就经常听到"需要安装JDK"."运行需要JRE"."JVM调优"等等,这里 ...

  9. 第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)

    第二种使用Ajax的形式将前台的数据传输到后台:https://blog.csdn.net/weixin_43304253/article/details/120335657 1.form表单 引入了 ...

  10. 齐博x2向上滚动特效

    要实现图中圈起来的向上滚动特效,大家可以参考下面的代码 <!--滚动开始--> <style type="text/css"> .auto-roll{ he ...