<泛> 归并排序 及 逆序对
今天写一个归并排序的模板,返回值为该序列的逆序对数
基本思路
归并排序就是利用二分的思想,将区间无限递归二分,直到当前划分区间只包含一个元素或没有元素的时候(我们认为这个序列是自动有序的),我们回溯到上一层,然后将当前层的左右两个区间合并为一个有序序列,然后继续回溯,回溯之后,当前层的左右两个区间都应该分别是已经经过合并的有序子区间,我们将这两个有序子区间再进行有序合并,再返回上一层,直到返回最大区间,则合并最大区间的左右有序子区间,得到有序序列。
流程演示
比如:22 3 1 5 4 7 9 1 8 0
红色区间划分:22 3 1 5 4
左边: 3 右边 5 4
左边:合并有序:3 22
右边:5 4区间递归返回时候变为:4 5
右边合并:1 4 5
左右区间合并为一个区间:1 3 4 5 22
至此左侧区间处理完毕
右侧区间同理,得到有序序列:0 1 7 8 9
最后合并整个区间
0 1 1 3 4 5 7 8 9 22
逆序对数
我们利用归并的思想,它会将每个区间细分到最小,返回整合的时候,会进行左右区间合并,合并的时候就要比较左右区间当前值那个大,然后取小的那个,我们可以在比较的时候做记录,如果左侧的值小于右侧,我们就做记录,这样一路回溯,就会找到所有的逆序对数。
我们利用归并排序的返回值来将此记录值输出到外部
泛型代码:
template<typename value_type, typename value_Ptr>
int merge_sort(const value_Ptr& begin, const value_Ptr& end)
{
static std::vector<value_type> to(end - begin);
static int cnt{ }; //记录逆序对数
if (end - begin <= )return ; value_Ptr mid = begin + (end - begin) / ; merge_sort<value_type>(begin, mid);
merge_sort<value_type>(mid, end); //将上述两段区间顺序排列
value_Ptr l = begin, r = mid;
int k{ }, index{ }; while (l < mid && r < end)
if (*l < *r)to[k++] = *l++;
else //如果左侧值小于右侧
{
cnt += mid - l; //逆序对数记录
to[k++] = *r++;
} while (l < mid)to[k++] = *l++;
while (r < end)to[k++] = *r++; for (index = ; begin + index < end; ++index)*(begin + index) = to[index]; return cnt;
}
测试与使用
#include <iostream>
#include <vector> using namespace std; int main()
{
ios::sync_with_stdio(false);
int list[]{ ,,,,,,,,, };
vector<int> v{ list,list + }; int cnt = merge_sort<int>(list + , list + );
merge_sort<int>(v.begin(), v.end());
for (auto it : v)cout << it << " ";
cout << endl;
for (auto it : list)cout << it << " ";
cout << endl;
cout << "逆序对数:" << cnt << endl << endl; char list_[]{ 'r','c','','A','z','b','','','r', '' };
vector<char>v_{ list_,list_ + }; cnt = merge_sort<char>(list_ + , list_ + );
merge_sort<char>(v_.begin(), v_.end());
for (auto it : v_)cout << it << " ";
cout << endl;
for (auto it : list_)cout << it << " ";
cout << endl;
cout << "逆序对数:" << cnt << endl << endl;
}
时间复杂度为:O(N * log N)
感谢您的阅读,生活愉快~
<泛> 归并排序 及 逆序对的更多相关文章
- 2014 HDU多校弟五场A题 【归并排序求逆序对】
这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...
- hihoCoder_二分·归并排序之逆序对
一.题目 题目1 : 二分·归并排序之逆序对 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 在上一回.上上回以及上上上回里我们知道Nettle在玩<艦これ&g ...
- 归并排序&&归并排序求逆序对
归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序 ...
- 【BZOJ4769】超级贞鱼 归并排序求逆序对
[BZOJ4769]超级贞鱼 Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的左脚和右脚上各有一个数.有一天,K只贞鱼兴致来潮,排成一列,从左到右第i ...
- POJ-排序-归并排序与逆序对
排序:归并排序与逆序对 一.概念 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序 ...
- poj2299(归并排序求逆序对)
题目链接:https://vjudge.net/problem/POJ-2299 题意:给定一个序列,每次只能交换邻近的两个元素,问要交换多少次才能使序列按升序排列. 思路:本质就是求逆序对.我们用归 ...
- 归并排序+归并排序求逆序对(例题P1908)
归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然 ...
- 归并排序求逆序对(poj 2299)
归并排序求逆序对 题目大意 给你多个序列,让你求出每个序列中逆序对的数量. 输入:每组数据以一个数 n 开头,以下n行,每行一个数字,代表这个序列: 输出:对于输出对应该组数据的逆序对的数量: 顺便在 ...
- HDU 3743 Frosh Week(归并排序求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程 ...
随机推荐
- don't run elasticsearch as root.
因为安全问题elasticsearch 不让用root用户直接运行,所以要创建新用户 第一步:liunx创建新用户 adduser XXX 然后给创建的用户加密码 passwd XXX ...
- HDU 4690 EBCDIC 2013 Multi-University Training Contest 9
解题报告:一个模拟题,有两张表格,然后输入一个字符在第一章表格中的位置,让你找出这个字符在第二章表对应的位置. 我欧诺个的是暴力打表,输了两百多个数字,时间复杂度直接降到O(1),这题觉得比较坑的就是 ...
- HDU 3535 AreYouBusy (混合背包之分组背包)
题目链接 Problem Description Happy New Term! As having become a junior, xiaoA recognizes that there is n ...
- Velocity VelocityEngine 支持多种loader 乱码问题
最近升级团队的代码生成工具,此工具是velocity实现的. 之前习惯使用UTF-8编码,现在团队使用GBK. 所以遇到一种场景,模板文件使用UTF-8(习惯了所有任性),输出文件使用GBK(项目需要 ...
- Shell-修改MySQL默认root密码
Code: mysqltmppwd=`cat /tmp/.mysql_secret | cut -b 87-102` mysqladmin -u root -p${mysqltmppwd} passw ...
- Linux学习笔记-文件处理和权限命令
目录 文件处理命令 touch cat tac more less head tail 链接命令 ln 权限命令 chmod 权限管理命令 chown chgrp umask 文件处理命令 touch ...
- CEC2017 benchmark function调用接口
CEC2017 benchmark function可以从这里下载. 导师最近给了个课题让我自己研究,跟智能优化算法相关的,必不可免的要用到最新的CEC2017 benchmark function, ...
- Python基础:内置常量
本文根据Python 3.6.5的官文Built-in Constants编写,官文比较短,大家可以直接看原文. 有一些存在于 内置名称空间(the built-in namespace) 的常量,如 ...
- java基础19 导包和“命令行”打jar包
1.导包 1.1.包 java中的包就相当于Windows文件夹 编译格式:javac -d . 类名.java 1.2.包的作用 1.解决了类名重复冲突的问题 2.便于软件版本的 ...
- Service(一):认识service、绑定Service
Activity是与用户打交道的,而Service是在后台运行的. 这个程序介绍了下如何启动和停止一个Service,以及在后台打印消息,我添加了一些注释. 在activity_main中将布局改为线 ...