nwpu-2020级算法实验1-problemB

Overview

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

有两种实现方式:

  • 自上而下的递归

    • 所有的递归都可以由迭代重写。

  • 自下而上的迭代

算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

  4. 重复步骤 3 直到某一指针达到序列尾;

  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

其实就是leetcode中我做过的暴力合并数组

链接:4. 寻找两个正序数组的中位数 - 力扣(LeetCode) (leetcode-cn.com)

直观演示

算法分析

动图展示了我们实现算法的过程,而这个分治图静态展示了递归的流程。

:递归拆分子序列,递归深度易得logn

:将有序子序列合并为更大的有序序列。

下面是治的最后一步的过程(熟练可略过):

算法实现

C递归

 1 //归并排序递归
2 #include<stdio.h>
3 //#include<stdlib.h>
4 //#include<iostream>
5 using namespace std;
6 void merge_sort_recursive(int arr[], int reg[], int start, int end) {
7 if (start >= end)
8 return;
9 //停止递归的条件,即只有单个元素时必定有序
10 int len = end - start, mid = (len >> 1) + start;
11 int start1 = start, end1 = mid;//第一个数组
12 int start2 = mid + 1, end2 = end;//第二个数组
13 merge_sort_recursive(arr, reg, start1, end1);
14 merge_sort_recursive(arr, reg, start2, end2);
15 //将数组拆分,直到上面的if生效(即每个子序列只有单个元素),此时停止递归,开始回溯
16 int k = start;
17 while (start1 <= end1 && start2 <= end2)
18 reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
19 //这种写法更为简洁,实现的就是谁小谁放进去
20 while (start1 <= end1)
21 reg[k++] = arr[start1++];
22 while (start2 <= end2)
23 reg[k++] = arr[start2++];
24 //多余元素直接放入reg
25 for (k = start; k <= end; k++)
26 arr[k] = reg[k];
27 //一次返回赋值,即把reg里排好序的元素粘回arr
28 }
29 ​
30 void merge_sort(int arr[], const int len) {
31 int reg[len];//构造算法步骤中所说的新的数组
32 merge_sort_recursive(arr, reg, 0, len - 1);
33 //启动递归
34 //输出
35 for(int i = 0; i < len; i++){
36 printf("%d\n", arr[i]);
37 }
38 //此处还可以clear *reg来保证代码安全。
39 }
40 int main(){
41 int n;
42 scanf("%d", &n);
43 int Array[n];
44 for(int i = 0; i < n; i++){
45 scanf("%d", &Array[i]);
46 }
47 merge_sort(Array, n);
48 return 0;
49 }

参考文章:

1.5 归并排序 | 菜鸟教程 (runoob.com)

算法学习->归并排序的更多相关文章

  1. Java常见排序算法之归并排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  2. 啃算法:归并排序及JavaScript实现

    在学习归并排序之前,有必要了解分治法,因为归并排序正是应用了分治模式.(基本定义摘自<算法导论>) 一.分治法 1.思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些 ...

  3. DSP算法学习-过采样技术

    DSP算法学习-过采样技术 彭会锋 2015-04-27 23:23:47 参考论文: 1 http://wr.lib.tsinghua.edu.cn/sites/default/files/1207 ...

  4. 算法学习之C语言基础

    算法学习,先熟悉一下C语言哈!!! #include <conio.h> #include<stdio.h> int main(){ printf(+); getch(); ; ...

  5. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  6. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  7. 算法学习之BFS、DFS入门

    算法学习之BFS.DFS入门 0x1 问题描述 迷宫的最短路径 给定一个大小为N*M的迷宫.迷宫由通道和墙壁组成,每一步可以向相邻的上下左右四格的通道移动.请求出从起点到终点所需的最小步数.如果不能到 ...

  8. 二次剩余Cipolla算法学习笔记

    对于同余式 \[x^2 \equiv n \pmod p\] 若对于给定的\(n, P\),存在\(x\)满足上面的式子,则乘\(n\)在模\(p\)意义下是二次剩余,否则为非二次剩余 我们需要计算的 ...

  9. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

随机推荐

  1. 跟我一起用unity做小地图!

    lol的小地图 转载爬虫请自重,未问先转没排面 不爱多做铺垫,小地图对于一些游戏来说多重要大家都懂,不然你也不会来看我这篇文章的,对不对? 话不多说,开搞! 一.主体功能 一般来说,游戏里的迷你地图都 ...

  2. Blazor WebAssembly 应用程序中进行 HTTP 请求

    翻译自 Waqas Anwar 2021年5月13日的文章 <Making HTTP Requests in Blazor WebAssembly Apps> [1] 在我的前篇文章< ...

  3. 设置 Qt GUI程序 printf输出到独立控制台

  4. Robot framework随机文件

    *** Variables *** @{Example} One Two Three *** Test Cases *** Example ${value}= Evaluate random.choi ...

  5. constexpr-C++11

    constexpr和常量表达式 常量表达式(const expression)是指值不会改变并且在编译过程就能得到计算结果的表达式.显然,字面值属于常量表达式,用常量表达式初始化的const对象也是常 ...

  6. GUI常用监听事件

    概念 对鼠标.键盘等一系列事件做出相应的反馈 事件监听 //创建监听事件 public class Demo { public static void main(String[] args) { Fr ...

  7. vue 手机号码隐藏中间

    template {{ phone | mobileFilter }}   data export default { filters:{         mobileFilter(val){     ...

  8. 从IT圈“鄙视链”看前端开发有多难?

    如今"鄙视链"体现在生活的方方面面,各行各业都有默认一致的鄙视链.IT圈子因为开发语言多样.工程师岗位种类多.技术框架多,也有自己圈子内的鄙视链.按照开发工程师的岗位形成的鄙视链是 ...

  9. Redis++:Redis 内存爆满 之 淘汰策略

    前言: 我们的redis使用的是内存空间来存储数据的,但是内存空间毕竟有限,随着我们存储数据的不断增长,当超过了我们的内存大小时,即在redis中设置的缓存大小(maxmeory 4GB),redis ...

  10. Model 特性

    表 1 AssociatedMetadataTypeTypeDescriptionProvider 通过添加在关联类中定义的特性和属性信息,从而扩展某个类的元数据信息. AssociationAttr ...