【算法导论】【ACM】归并排序总结
许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关地若干子问题。这些算法典型的遵循分治法地思想:将原问题分解成几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。
分治模式在每层递归时都有三个步骤:
- 分解原问题为若干子问题,这些子问题是原问题规模较小的实例。
- 解决这些子问题,递归地求解各子问题。若子问题规模足够小,则直接求解。
- 合并这些子问题的解成原问题的解。
归并排序:完全遵循分治模式。
- 分解:分解该待排序的n个元素的序列成各具n/2元素的两个子序列。
- 解决:使用归并排序递归地解决两个子序列。
- 合并:合并两个已排序的子序列以产生以排序的答案。
归并排序示意图:
归并排序实现:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
const int MAXN = 1e5;
int a[MAXN], T[MAXN];
void merge_sort(int* A, int x, int y, int* T);
int main()
{int n;cin>>n;for (int i = 0; i < n; i++) {cin >> a[i];}merge_sort(a, 0, n, T);for (int i = 0; i < n; i++) {cout << a[i] << endl;}return 0;
}void merge_sort(int* A, int x, int y, int* T)
{if (y - x > 1) {int m = x + (y - x) / 2;int p = x, q = m, i = x;merge_sort(A, x, m, T);merge_sort(A, m, y, T);while (p < m || q < y) {if (q >= y || (p < m && A[p] <= A[q])) {T[i++] = A[p++];} else {T[i++] = A[q++];}}for (int i = x; i < y; i++) {A[i] = T[i];}}
}
例题1:
Write a program of a Merge Sort algorithm implemented by the following pseudocode. You should also report the number of comparisons in the Merge function.
Merge(A, left, mid, right)n1 = mid - left;n2 = right - mid;create array L[0...n1], R[0...n2]for i = 0 to n1-1do L[i] = A[left + i]for i = 0 to n2-1do R[i] = A[mid + i]L[n1] = SENTINELR[n2] = SENTINELi = 0;j = 0;for k = left to right-1if L[i] <= R[j]then A[k] = L[i]i = i + 1else A[k] = R[j]j = j + 1Merge-Sort(A, left, right){if left+1 < rightthen mid = (left + right)/2;call Merge-Sort(A, left, mid)call Merge-Sort(A, mid, right)call Merge(A, left, mid, right)
Input
In the first line n is given. In the second line, n integers are given.
Output
In the first line, print the sequence S. Two consequtive elements should be separated by a space character.
In the second line, print the number of comparisons.
Constraints
- n ≤ 500000
- 0 ≤ an element in S ≤ 109
Sample Input 1
10 8 5 9 2 6 3 7 1 10 4
Sample Output 1
1 2 3 4 5 6 7 8 9 10 34
Mem (MB):6.5
#include <stdio.h>
#include <stdlib.h>
const int maxn = 500000 + 100;
int a[maxn],T[maxn];
int count=0;
void merge_sort(int *A,int x,int y,int *T);
int main ()
{int n,i;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);merge_sort(a,0,n,T);for(i=0;i<n;i++){if(i!=n-1)printf("%d ",a[i]);elseprintf("%d\n",a[i]);}printf("%d\n",count);}return 0;
}
void merge_sort(int *A,int x,int y,int *T)
{if(y-x>1){int mid=x+(y-x)/2;int p=x,q=mid,i=x;merge_sort(A,x,mid,T);merge_sort(A,mid,y,T);while(p<mid || q<y){if(q>=y || (p<mid && A[p]<=A[q])){count++;T[i++]=A[p++];}else{count++;T[i++]=A[q++];}}for(i=x;i<y;i++){A[i]=T[i];}}
}
Mem (MB):7
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int maxn = 500000;
const int INF = 0x3f3f3f3f;
int a[maxn],L[maxn/2+2],R[maxn/2+2];
int count;
void merge(int array[],int p,int q,int r)
{int n1=q-p,n2=r-q,i,j,k;for(i=0;i<n1;i++){L[i]=array[p+i];}L[n1]=INF;R[0]=-1;for(j=0;j<n2;j++){R[j]=array[q+j]; }R[n2]=INF;i=0;j=0;for(k=p;k<r;k++){if(L[i]<=R[j]){count++;array[k]=L[i++];}else{count++;array[k]=R[j++];}}
}void merge_sort(int array[],int p,int r)
{if(p+1<r){int q=(p+r)/2;merge_sort(array,p,q);merge_sort(array,q,r);merge(array,p,q,r); }
}int main ()
{int len,i;while(scanf("%d",&len)!=EOF){count=0; for(i=0;i<len;i++){scanf("%d",&a[i]);}merge_sort(a,0,len);for(int i=0;i<len;i++){if(i!=len-1)printf("%d ",a[i]);elseprintf("%d\n",a[i]);}printf("%d\n",count); }return 0;
}
例题2:
POJ 2299
求逆序对
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5 9 1 0 5 4 3 1 2 3 0Sample Output
6 0
对于不同的排名结果可以用逆序来评价它们之间的差异。考虑1,2,…,n的排列i1,i2,…,in,如果其中存在j,k,满足j < k 且 ij > ik, 那么就称(ij,ik)是这个排列的一个逆序。
一个排列含有逆序的个数称为这个排列的逆序数。例如排列 263451 含有8个逆序(2,1),(6,3),(6,4),(6,5),(6,1),(3,1),(4,1),(5,1),因此该排列的逆序数就是8。显然,由1,2,…,n 构成的所有n!个排列中,最小的逆序数是0,对应的排列就是1,2,…,n;最大的逆序数是n(n-1)/2,对应的排列就是n,(n-1),…,2,1。逆序数越大的排列与原始排列的差异度就越大。
现给定1,2,…,n的一个排列,求它的逆序数。
输入
第一行是一个整数n,表示该排列有n个数(0<=n <= 100000)。
第二行是n个不同的正整数,之间以空格隔开,表示该排列。输出输出该排列的逆序数
例如:输入:6 2 6 3 4 5 1输出:8
基本思路:
1.使用二分归并排序法【分治法】进行求解;
2.将序列依此划分为两两相等的子序列;
3.对每个子序列进行排序(比较r[i]>r[j],如果满足条件,则求该子序列的逆序数count=m-i+1,其中m=(start+end)/2)
4.接着合并子序列即可。
#include <stdio.h>
#include <stdlib.h>
const int maxn = 500000+100;
long long count;
int a[maxn],r1[maxn];/*合并子序列*/
void Merge(int s,int m,int t)
{int i=s,j=m+1,k=s;while(i<=m && j<=t){if(a[i]<=a[j])r1[k++]=a[i++];else{r1[k++]=a[j++];count+=(m-i+1);}}while(i<=m)r1[k++]=a[i++];while(j<=t)r1[k++]=a[j++];for(i=s;i<=t;i++)a[i]=r1[i];
} /*对序列r[s]-r[t]进行归并排序*/
void MergeSort(int s,int t)
{int m;if(s==t) return;else{m=(s+t)/2;MergeSort(s,m);MergeSort(m+1,t);Merge(s,m,t);}
}int main()
{int n,i;while(scanf("%d",&n)!=EOF && n){count=0;for(i=0;i<n;i++)scanf("%d",&a[i]);MergeSort(0,n-1);printf("%lld\n",count);}return 0;
}
相关文章:

C++ 纯虚方法
1、纯虚方法解决什么样的问题,为什么要设计出纯虚方法? 考虑下面的需求,基类声明了一个方法,这个方法只针对具体的子类才有意义,比如Animal的Eat()方法,调用Animal的Eat方法是没有意义的。比如Dog吃肉&…

C++标准库中各种排序归纳
一、简介所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。我们在编程过程中会经常接触到排序,比如游戏中的排行榜等。C标准库中提供了各种不同的排序算法,这篇博客将逐一介绍。…
【数据结构】最小生成树 Prim算法 Kruskal算法
最小生成树应用场景: 假设以下场景,有一块木板,板上钉上一些钉子,这些钉子可以由一些细绳连接起来。假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样得情况,即用最少的细绳把所有的钉子连…

.net内存回收与Dispose﹐Close﹐Finalize方法
.net内存回收与Dispose﹐Close﹐Finalize方法 一. net的对象使用一般分为三种情况﹕ 1.创建对象2.使用对象3.释放对象 二.创建对象1.创建对象实际分为两个步骤﹕变量类型宣告和初始化对象 2.变量类型宣告(declare),如﹕ FileStream fs这行代码会在当前的变量作用域空间(栈或堆)…
SLAM学习--------相机位姿表示-李群李代数
slam 求解相机的位姿求解核心思想:将有约束的李群问题转换成无约束的李代数问题,然后使用高斯牛顿算法或者LM(列文伯格-马夸尔特法)求解。 人们找了很多以相机位姿为变量的误差函数,比如光度误差,重投影误差,3D几何误…
【ACM】杭电OJ 2063
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid2063 借鉴:http://blog.sina.com.cn/s/blog_ac5ed4f30101ewjk.html 二分图(二部图):图论中的一种特殊模型。设G(V,E)是一个无向图,如果顶点V可以分割…

AngularJs表单自动验证
angular-auto-validate 地址:https://github.com/jonsamwell/angular-auto-validate 引用: <script src"/Assets/JS/AngularJS/angular-auto-validate/dist/jcs-auto-validate.js" charset"utf-8"></script> 依赖&#…
AlwaysVisibleControlExtender
今天早上学习了AlwaysVisibleControlExtender控件,感觉还是不错。下午就写点东西,总结一下使用方法。 简单使用示例(显示当前时间) 1)在VS下,新建一个ASP.NET AJAX-Enabled Web Project项目,命名为AlwaysVisibleC…
Depth graph
深度相机 定义:可以直接获取场景中物体距离摄像头物理距离的相机。在计算机视觉系统中,三维场景信息为图像分割、目标检测、物体跟踪等各类计算机视觉应用提供了更多的可能性,而深度图像(Depth map)作为一种普遍的三维…

【ACM】POJ 1852
【问题描述】 一队蚂蚁在一根水平杆上行走,每只蚂蚁固定速度 1cm/s. 当一只蚂蚁走到杆的尽头时,立即从秆上掉落. 当两只蚂蚁相遇时它们会掉头向相反的方向前进. 我们知道每只蚂蚁在杆上的初始位置, 但是, 我们不知道蚂蚁向哪个方向前行. 你的任务是计算…

ZStack--通过Ansible实现全自动化
2019独角兽企业重金招聘Python工程师标准>>> Agent是一种常见的IaaS软件管理设备的方式;例如,ZStack使用Python agents去管理KVM主机。因为海量的设备,安装和升级agents成为巨大的挑战,所以大多数IaaS软件把这个问题留…
SVO 半直接视觉里程计
SVO 从名字来看,是半直接视觉里程计,所谓半直接是指通过对图像中的特征点图像块进行直接匹配来获取相机位姿,而不像直接匹配法那样对整个图像使用直接匹配。整幅图像的直接匹配法常见于RGBD传感器,因为RGBD传感器能获取整幅图像的…

css构造文本
1. 1. 文本缩进text-indent:值;值为数字,最常用的数值单位是px(像素),也可以直接是百分比!text-indent:100px;text-indent:10%;2. 文本对齐text-align:对其方式;可以的值为:left、center、right3. 文本行高…
【数据结构】单链表的逆序输出(两种方法)
第一种方法:转换指针方向 即:将一个已经创建好的单链表进行指针域的改变 今天突然被问到单链表逆序的问题,弄了好久才看出别人的程序有啥问题,就重新写了一遍。 今天才在CSDN客户端上看到美团的面试题是冒泡排序。 一个看似简单…

koa+mongoose基础入门
1.mongoose基本使用 1.安装mongodb npm install mongodb 2.引入mongodb数据表,连接mongodb,通过node来对mongodb进行异步的增删改查 const mongodb requrie(mongodb); mongodb.MongoClient.connect("mongodb://localhost/db1", function(err,…

视觉SLAM学习(三)--------SLAM 综述
SLAM概述 参考资料分享来自本人博客:https://blog.csdn.net/Darlingqiang/article/details/78840931 SLAM一般处理流程包括track和map两部分。所谓的track是用来估计相机的位姿,也叫front-end。而map部分(back-end)则是深度的构建,通过前面…
【数据结构】所有顶点对的最短路径 Floyd算法
所有顶点对的最短路径问题是指:对于给定的有向图G(V,E),求任意一对顶点之间的最短路径。 可以求解得到的 的递推公式: #include <stdio.h> #include <stdlib.h> const int FINITY 5000; const int M 20; typedef struct {ch…

backbone学习总结(二)
今天来看下backbone的路由控制的功能。其实个人感觉backbone,模块就那么几个,熟悉它的框架结构,以及组成,就差不多。 废话不多说,我们来看看还剩下的功能。 关于路由和历史管理 通过 Backbone.Router.extend 来创建路由…

人工智能--野人过河
课程简介 人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能的定义可以分为两部分,即“人工”和“智能”。“人工”比较好…

java对cookie的操作
原文:http://www.cnblogs.com/muzongyan/archive/2010/08/30/1812552.html java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题。 建立一个无生命周期的cookie,即随着…

【ACM】POJ 3069
【问题描述】 Saruman the White must lead his army along a straight path from Isengard to Helm’s Deep. To keep track of his forces, Saruman distributes seeing stones, known as palantirs, among the troops. Each palantir has a maximum effective range of R u…

sparkCore源码解析之思维脑图
2019独角兽企业重金招聘Python工程师标准>>> 在学习sparkCore时,有几个模块的概念理解不是很透彻,故对照源码进行学习,并将结果一脑图的形式呈现,方便后续的持续学习。 详细内容见: sparkCore源码解析之blo…

pangilin 安装编译
make pangolin 的时候报错 ootsun:/home/sun/AR/orb/Pangolin-0.5/build# make [ 1%] Building CXX object src/CMakeFiles/pangolin.dir/log/packetstream.cpp.o /home/sun/AR/orb/Pangolin-0.5/src/log/packetstream.cpp: 在函数‘void pangolin::WaitUntilPlaybackTim…

PHP实现求阶乘
function factorial ($x){if ($x > 1) {$s $x * factorial ($x - 1);} else {$s $x;}return $s; }$x 100;echo $x."的阶乘的为".factorial($x);转载于:https://blog.51cto.com/chensenlin/1854679

【ACM】杭电OJ 2064(汉诺塔III)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid2064 思路: 1、将n-1个盘从A移到C f(n-1)次 2、将第n个从A移到B 1次 3、将n-1个盘从C移到A f(n-1)次 4、将第n个从B移到C 1次 5、将n-1个盘从A移到C f(n-1)次 #include<cstdio> #inclu…

文件上传至阿里云
public static String uploadFile2OSS(InputStream instream, String fileName) throws IOException {String imageName null;OSSClient ossClient null;try {ClientConfiguration conf new ClientConfiguration();// 请求超时时间设置conf.setConnectionTimeout(5000);// 请…

ORB-SLAM2安装
安装顺利与否可能会与Ubuntu版本有关。(ubuntu16.04 gcc4.8.5这个很重要偶,本班的直接决定Pangolin能不能安装成功,如果遇到哦问题的朋友可以参考一下链接 http://blog.csdn.net/Darlingqiang/article/details/78928873)亲测可用…
iOS 系统分析(一) 阅读内核准备知识
原文出自【听云技术博客】:http://blog.tingyun.com/web/a... 0x01 iOS体系架构1.1 iOS 系统的整体体系架构 用户体验( The User Experience layer ):SpringBoard 同时支持 Spotlight。 应用软件开发框架(The Application Frameworks layer&a…
【数据结构】拓扑排序
如果一个有向图中没有包含简单的回路,这样的图为有向无环图。 图中的顶点代表事件(活动),图中的有向边说明了事件之间的先后关系。这种用顶点表示活动,用弧表示活动时间的优先关系的有向图称为顶点表示活动的网&#…

Java8自定义条件让集合分组
** 将一个指定类型对象的集合按照自定义的一个操作分组; 每组对应一个List、最终返回结果类型是:List<List<T>> param <T>*/static class GroupToList<T> implements Collector<T, List<List<T>>, List<List<T>&g…