一、前言

您好,我是夏日弥,叫我“夏”或者“小弥”都可以。

今天先来讲 归并排序 ——一种时间复杂度为 N●logN 的排序算法;

让我们看看今天我们将要进入的主题吧!

二、归并排序

2.1、概念&思想:

归并排序是一种稳定的,时间复杂度为N●logN的排序算法,它由两个部分组成:

递归划分(divide):将数组划分成左右两个部分,再将左右两个部分分别再划分成两个部分,以此类推,直至数组里的元素被划分成数个只有一个元素的数组;

图解如下:(图丑莫见怪,小夏不会画画哈)

我们把数组划分成这个样子后,递归合并回去;

合并数组:数组元素较小的放在前面,数组元素较大的放在后面;

图解如下:

        我们将两个小数组合并成一个局部有序的数组:

以1248和3567为例:

我们将 i 和 j 指向的那个较小数字拿出来放到 tmp[0] 里面:

也就是拿出 1 放到 tmp[0] 里,随后我们移动指针 i 前进,tmp 的指针 t 前进;

再比较2 和 3,把2 放进 tmp[1] 里,移动指针 i 和 t 前进;

这次是3 和 4比较,把3放进去,移动指针 j 和 t前进;

依次类推,直到 i 或 j 走到终点,再将剩余的数字全部复刻进tmp;

1248 就是 12 和  48  以此种规则递归而来;3567依次类推;

2.2、代码实现:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n;
int a[N],tmp[N];
unsigned int result;
void merge_sort(int a[],int l,int r){if( l >= r)return  ;//递归的排序的算法必须考虑到的,当数组只剩一个元素时就要返回单个元素了;int mid = (r + l )/2;//定义中点;merge_sort(a,l,mid);//递归前半部分;merge_sort(a,mid+1,r);//递归后半部分;/* 以下为缝合两个有序的数组的部分 */int i = l;//定义第一数组的前指针;int j = mid+1;//定义第二数组的前指针;int t = 0;//定义暂存数组的前指针; while(i <= mid && j <= r ) //扫描第一数组和第二数组; {if(a[i] <= a[j]){tmp[t++] = a[i++];//把较小的数字放入tmp数组中,再分别移动t针和i针; }else{tmp[t++] = a[j++]; }}/* 以下为补齐部分,将第一或者第二数组的剩余部分补齐进入tmp数组;*/while(i <= mid ){tmp[t++] = a[i++]; }while(j <= r ){tmp[t++] = a[j++];}/* 以下为复制补全部分*/ for(int i = l ,j = 0; i <= r ;i++,j++ ){a[i] = tmp[j];}/*为什么要从 i = l 开始?为什么是i针扫到r结束 ?*/
}
int main(){cin>>n;for(int i = 0;i<n;i++)cin>>a[i];merge_sort(a,0,n-1); for(int i = 0 ;i<n;i++)cout<<a[i]<<" ";
} 

经典的递归排序算法模板;

merge_sort (int a[],int l,int r)
//第一个参数为需要排序的数组,第二个参数为排序起点,第三个参数为排序终点

三、例题:

3.1、归并排序:

787. 归并排序 - AcWing题库

使用上面的模板就可以AC了,更多是锻炼您对模板的记忆;

3.2、活动 - AcWing

唔....我们将利用递归思想分析这个问题:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n;
int a[N],tmp[N];
unsigned int result =  0;
void merge_sort(int a[],int l,int r){if( l >= r)return  ;//递归的排序的算法必须考虑到的,当数组只剩一个元素时就要返回单个元素了;int mid = (r + l )/2;//定义中点;merge_sort(a,l,mid);//递归前半部分;merge_sort(a,mid+1,r);//递归后半部分;/* 以下为缝合两个有序的数组的部分 */int i = l;//定义第一数组的前指针;int j = mid+1;//定义第二数组的前指针;int t = 0;//定义暂存数组的前指针; while(i <= mid && j <= r ) //扫描第一数组和第二数组; {if(a[i] <= a[j]){tmp[t++] = a[i++];//把较小的数字放入tmp数组中,再分别移动t针和i针; }else{tmp[t++] = a[j++];result += (mid - i + 1);}}/* 以下为补齐部分,将第一或者第二数组的剩余部分补齐进入tmp数组;*/while(i <= mid ){tmp[t++] = a[i++]; }while(j <= r ){tmp[t++] = a[j++];result += (mid-i+1);}/* 以下为复制补全部分*/ for(int i = l ,j = 0; i <= r ;i++,j++ ){a[i] = tmp[j];}/*为什么要从 i = l 开始?为什么是i针扫到r结束 ?*/
}
int main(){cin>>n;for(int i = 0;i<n;i++)cin>>a[i];merge_sort(a,0,n-1);cout<<result;
} 

四、尾声

感谢您的阅读和理解。

小夏累了,下周以及下下周预计会比较忙,有不足之处还望您指出。

特别鸣谢 lym 对本文的指导。

归并排序的思想以及应用——试解《逆序对的数量》相关推荐

  1. -9 逆序输出一个整数的各位数字_【每日算法】基础算法——归并排序[求逆序对的数量](四)(思想很经典)...

    题目内容 给定一个长度为n的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆 ...

  2. AcWing 788 逆序对的数量-归并排序

    给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j] ,则其为一个逆序对:否则不 ...

  3. ACM算法训练【逆序对的数量】

    ACM算法训练[逆序对的数量] 题目说明 数据范围 样例 分析与代码 题目说明 数据范围 样例 分析与代码 ①归并排序基本思想: ②在归并的过程中,逆序对出现的三种情况: a.全部出现在左边的区间 b ...

  4. acwing788. 逆序对的数量

    给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对:否则不是 ...

  5. 788. 逆序对的数量

    给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对:否则不是 ...

  6. [个人记录] AcWing 788 逆序对的数量

    788. 逆序对的数量 VIEDIO #include <iostream> #include <cmath> #include <cstring> #includ ...

  7. acwing788. 逆序对的数量(蓝桥杯)

    题目:788. 逆序对的数量 #include<bits/stdc++.h>using namespace std; typedef long long LL; const int N=1 ...

  8. AcWing 788. 逆序对的数量

    题目连接 https://www.acwing.com/problem/content/790/ 思路 归并排序求逆序对是一个很经典的利用归并排序的特性的一个题目,上一篇博客讲到了归并排序的其实就是我 ...

  9. 【分治法】逆序对的数量(结合归并排序,含详细思想、解法、代码及注释)

    目录:

最新文章

  1. 今年两会大火的新基建,平均企业月薪1.63万 | 2020新基建中高端人才市场就业吸引力报告...
  2. 几条跟堆栈扯上关系的汇编指令
  3. 一次群晖中勒索病毒后的应急响应
  4. 关于盘符里某些文件夹删除不了的解决方案研究
  5. XML-RPC协议学习
  6. c语言函数写巴德歌赫猜想,{转帖}我们还有创造力么
  7. 开发、运维过程中解决问题的通用步骤
  8. 智慧水务项目建设方案
  9. referenced before assignment
  10. oracle导入dmp文件数据不全,oracle导入dmp文件(恢复数据)
  11. SQL中where in的用法
  12. 在ubuntu中使用7z压缩命令分卷压缩超大文件
  13. flutter 可拖拽吸边的悬浮按钮,悬浮布局;
  14. matlab二元不等式,大神们,求个解多元一次不等式的代码,要所有整数解
  15. 安装配置Tomcat6教程
  16. 链接预测(Link Prediction)
  17. html制作电影界面,电影网站界面设计HTML_CSS模板
  18. 汇编语言--逻辑指令
  19. 运放如何产生三角波信号
  20. Linux ——objdump和readelf的使用

热门文章

  1. 威盛卖掉威睿电通CDMA技术:Intel也全网通了!
  2. 视频会议系统——多分屏
  3. 微信小程序中引用FontAwesome字体 最完整教程 附下载源码
  4. ESP8266-AP模式作服务器
  5. pageinspect
  6. 混合高斯模型原理和Lucas-Kanade方法介绍
  7. Beckhoff TwinCAT3.1 通过EtherCAT驱动电机(上)
  8. 中国制造挽救了特斯拉,否则它就被大众超越了
  9. PAT-A-1062 Talent and Virtue 【排序】
  10. VPD(Virtual Private Database)