归并排序的思想以及应用——试解《逆序对的数量》
一、前言
您好,我是夏日弥,叫我“夏”或者“小弥”都可以。
今天先来讲 归并排序 ——一种时间复杂度为 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 对本文的指导。
归并排序的思想以及应用——试解《逆序对的数量》相关推荐
- -9 逆序输出一个整数的各位数字_【每日算法】基础算法——归并排序[求逆序对的数量](四)(思想很经典)...
题目内容 给定一个长度为n的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆 ...
- AcWing 788 逆序对的数量-归并排序
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j] ,则其为一个逆序对:否则不 ...
- ACM算法训练【逆序对的数量】
ACM算法训练[逆序对的数量] 题目说明 数据范围 样例 分析与代码 题目说明 数据范围 样例 分析与代码 ①归并排序基本思想: ②在归并的过程中,逆序对出现的三种情况: a.全部出现在左边的区间 b ...
- acwing788. 逆序对的数量
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对:否则不是 ...
- 788. 逆序对的数量
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对:否则不是 ...
- [个人记录] AcWing 788 逆序对的数量
788. 逆序对的数量 VIEDIO #include <iostream> #include <cmath> #include <cstring> #includ ...
- acwing788. 逆序对的数量(蓝桥杯)
题目:788. 逆序对的数量 #include<bits/stdc++.h>using namespace std; typedef long long LL; const int N=1 ...
- AcWing 788. 逆序对的数量
题目连接 https://www.acwing.com/problem/content/790/ 思路 归并排序求逆序对是一个很经典的利用归并排序的特性的一个题目,上一篇博客讲到了归并排序的其实就是我 ...
- 【分治法】逆序对的数量(结合归并排序,含详细思想、解法、代码及注释)
目录:
最新文章
- 今年两会大火的新基建,平均企业月薪1.63万 | 2020新基建中高端人才市场就业吸引力报告...
- 几条跟堆栈扯上关系的汇编指令
- 一次群晖中勒索病毒后的应急响应
- 关于盘符里某些文件夹删除不了的解决方案研究
- XML-RPC协议学习
- c语言函数写巴德歌赫猜想,{转帖}我们还有创造力么
- 开发、运维过程中解决问题的通用步骤
- 智慧水务项目建设方案
- referenced before assignment
- oracle导入dmp文件数据不全,oracle导入dmp文件(恢复数据)
- SQL中where in的用法
- 在ubuntu中使用7z压缩命令分卷压缩超大文件
- flutter 可拖拽吸边的悬浮按钮,悬浮布局;
- matlab二元不等式,大神们,求个解多元一次不等式的代码,要所有整数解
- 安装配置Tomcat6教程
- 链接预测(Link Prediction)
- html制作电影界面,电影网站界面设计HTML_CSS模板
- 汇编语言--逻辑指令
- 运放如何产生三角波信号
- Linux ——objdump和readelf的使用