归并排序

AcWing 787.归并排序

回眸只為那壹抹淺笑 提交于 2020-02-04 09:39:20
AcWing 787.归并排序 题目描述 给定你一个长度为n的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有整数均在1~ 10 9 109范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1 ≤ n ≤ 100000 1≤n≤100000 输入样例: 5 3 1 2 4 5 输出样例: 1 2 3 4 5 归并排序的思路 选取中点,使区间分成左右两段 递归处理left,right两区间 归并(合二为一) 就是每次保证每个子区间是有序的,最后整个区间都是有序的 代码如下 1 #include <iostream> 2 using namespace std; 3 4 const int N = 1e6 + 10; 5 int a[N], temp[N], n; 6 7 void megerSort(int q[], int l, int r){ 8 if(l >= r) return; 9 10 int mid = (l + r) >> 1; 11 12 megerSort(q, l, mid); megerSort(q, mid + 1, r); 13 14 int i = l, j = mid + 1, k = 0;

归并排序及模板

跟風遠走 提交于 2020-02-01 22:03:25
文章目录 归并排序理解 归并排序模板 归并排序理解 归并排序的主要操作如下: (1)分解。把初始序列分成长度相同的左、右两个子序列,然后把每个子序列再分成更小的两个子序列,直到子序列只包含一个数。这个过程用递归实现。 (2)求解子问题,对子序列排序。最底层的子序列只包含一个数,其实不用排序。 (3)合并。归并两个有序的子序列,这是归并排序的主要操作。比如下面举例, 把a[ ]分成两个子序列,比较后存进b[ ] ,假设两个子序列已经分别排好序。 过程如下(有点丑…将就一下): 只要有一个子序列结束,就可以把另一个子序列后面的都放进去,因为是排好序的 归并排序的 时间复杂度 :对n个数进行排序: 需要log2(n)趟归并。 在每一趟归并中有很多次合并操作。共需O(n)次比较。所以时间复杂度为 归并排序模板 输入n个数,对n个数进行排序。 # include <iostream> using namespace std ; const int N = 1e6 + 10 ; int n ; int q [ N ] , temp [ N ] ; void merge ( int q [ ] , int l , int r ) { if ( l >= r ) return ; //满足条件不再往下进行 int mid = ( l + r ) / 2 ; merge ( q , l , mid

归并排序

不羁的心 提交于 2020-02-01 01:15:46
算法核心: 大 序 列 递 归 到 小 序 列 , 进 行 排 序 然 后 合 并 \color{red}{大序列递归到小序列,进行排序然后合并} 大 序 列 递 归 到 小 序 列 , 进 行 排 序 然 后 合 并 该 算 法 的 核 心 步 骤 在 于 — — 合 并 ! \color{red}{该算法的核心步骤在于——合并!} 该 算 法 的 核 心 步 骤 在 于 — — 合 并 ! 合 并 操 作 : \color{green}{合并操作:} 合 并 操 作 : mark1 mark2分别用来标记两个子段 抓 住 子 段 已 经 排 序 的 特 点 \color{red}{抓住子段已经排序的特点} 抓 住 子 段 已 经 排 序 的 特 点 每次把mark1 和mark2 中更小的放进去,放完即合并完毕~ void G ( int * head , int * temp , int start , int end ) { //head 为待排序序列 temp为暂存数组 //start和end 表示从start到end之间进行排序 int mark1 , mark2 ; //两子段合并时用的的标记变量 if ( start + 1 == end ) { //递归出口 if ( head [ start ] > head [ end ] ) { int temp =

归并排序_(模板)

早过忘川 提交于 2020-02-01 00:16:55
给定你一个长度为n的整数数列。请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。第二行包含 n 个整数(所有整数均在1~109范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1≤n≤100000 输入样例: 5 3 1 2 4 5 输出样例: 1 2 3 4 5 # include <iostream> # include <algorithm> using namespace std ; int aa [ 123456 ] ; int qq [ 123456 ] ; void merge_sort ( int aa [ ] , int l , int r ) { if ( l >= r ) return ; int mid = ( l + r ) / 2 ; merge_sort ( aa , l , mid ) ; merge_sort ( aa , mid + 1 , r ) ; int i = l , j = mid + 1 , k = 0 ; while ( i <= mid && j <= r ) { if ( aa [ i ] <= aa [ j ] ) qq [ k ++ ] = aa [ i ++ ] ; else qq [ k ++ ] =

归并排序

我怕爱的太早我们不能终老 提交于 2020-01-31 14:30:29
归并排序(英语:Merge sort,或mergesort),是创建在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 分治法: 分割:递归地把当前序列平均分割成两半。 集成:在保持元素顺序的同时将上一步得到的子序列集成到一起(归并)。 def merge(arr, l, m, r): n1 = m - l + 1 n2 = r- m # 创建临时数组 L = [0] * (n1) R = [0] * (n2) # 拷贝数据到临时数组 arrays L[] 和 R[] for i in range(0 , n1): L[i] = arr[l + i] for j in range(0 , n2): R[j] = arr[m + 1 + j] # 归并临时数组到 arr[l..r] i = 0 # 初始化第一个子数组的索引 j = 0 # 初始化第二个子数组的索引 k = l # 初始归并子数组的索引 while i < n1 and j < n2 : if L[i] <= R[j]: arr[k] = L[i] i += 1 else: arr[k] = R[j] j += 1 k += 1 # 拷贝 L[] 的保留元素 while i < n1: arr[k] = L[i] i += 1 k += 1 # 拷贝 R[

由递归排序引申出的小和问题和逆序数对问题

送分小仙女□ 提交于 2020-01-31 13:02:09
递归排序的思想是将带牌列数组不断的拆成俩部分,再将有序的左右的俩部分合并。 小和问题:在一个数组中,每一个数左边比当前小的数累加起来,叫做这个数组的小和。求一个数组的小和。 逆序对问题,在一个数组中,打印出数组所有左边数大于右边数的组合。 下面是归并排序的代码(go语言) // 写一个归并排序 func mergeSort(arr *[]int, l, r int) { // 这部分是拆 if l == r { return } mid := l + ((r - l) >> 1) mergeSort(arr, l, mid) mergeSort(arr, mid+1, r) merge(arr, l, mid, r) } func merge(arr *[]int, l, mid, r int) { p, q := l, mid+1 help := make([]int, r-l+1) i := 0 for p <= mid && q <= r { if (*arr)[p] <= (*arr)[q] { help[i] = (*arr)[p] p = p + 1 i = i + 1 } else { help[i] = (*arr)[q] q = q + 1 i = i + 1 } } for p <= mid { help[i] = (*arr)[p] p = p + 1 i =

mapreduce shuffle 和sort 详解

拈花ヽ惹草 提交于 2020-01-31 03:58:51
MapReduce 框架的核心步骤主要分两部分:Map 和Reduce。当你向 MapReduce 框架提交一个计算作业时,它会首先把计算作业拆分成若干个Map 任务,然后分配到不同的节点上去执行,每一个Map 任务处理输入数据中的一部分,当Map 任务完成后,它会生成一些中间文件,这些中间文件将会作为Reduce 任务的输入数据。Reduce 任务的主要目标就是把前面若干个Map 的输出汇总到一起并输出。 本文的重点是剖析 MapReduce 的核心过程—— Shuffle 和 Sort 。在本文中, Shuffle 是指从Map 产生输出开始,包括系统执行排序以及传送Map 输出到Reducer 作为输入的过程。在这里我们将去探究 Shuffle 是如何工作的,因为对基础的理解有助于对 MapReduce 程序进行调优。 首先从Map 端开始分析。 当Map 开始产生输出时,它并不是简单的把数据写到磁盘,因为频繁的磁盘操作会导致性能严重下降。它的处理过程更复杂,数据首先是写到内存中的一个缓冲区,并做了一些预排序,以提升效率。 每个Map 任务都有一个用来写入输出数据的循环内存缓冲区。这个缓冲区默认大小是100MB,可以通过 io.sort.mb 属性来设置具体大小。当缓冲区中的数据量达到一个特定阀值( io.sort.mb * io.sort.spill.percent ,其中

算法-归并排序

﹥>﹥吖頭↗ 提交于 2020-01-31 01:55:17
PS:公众号「让我遇见相似的灵魂」,回复对应关键字【获取算法竞赛资料】。 左手代码,右手吉他,这就是天下:如果有一天我遇见相似的灵魂 那它肯定是步履艰难 不被理解 喜黑怕光的。如果可以的话 让我触摸一下吧 它也一样孤独得太久。 不一样的文艺青年,不一样的程序猿。 归并 分治 确定分界点, 中心点 递归左边、右边 归并——合二为一(重难点) 特点 稳定的 时间复杂度:nlog2^n妥妥的 #include<iostream> using namespace std; const int N = 1e6 + 10; int n; //temp辅助数组存排序结果 int q[N], temp[N]; void merge_sort(int q[], int l, int r){ if(l >= r) return; //分界点(l+r)/2 int mid = l + r >> 1; //递归 merge_sort(q, l, mid), merge_sort(q, mid + 1, r); //k已排序个数,i左边起点,j右边起点 int k = 0, i = l, j = mid + 1; while(i <= mid && j <= r) if(q[i] <= q[j]) temp[k ++] = q[i ++]; else temp[k ++] = q[j ++]; /

【MapReduce】二、MapReduce编程模型

隐身守侯 提交于 2020-01-30 17:59:03
  通过前面的实例,可以基本了解MapReduce对于少量输入数据是如何工作的,但是MapReduce主要用于面向大规模数据集的并行计算。所以,还需要重点了解MapReduce的并行编程模型和运行机制。   我们知道, MapReduce计算模型主要由三个阶段构成:Map、shuffle、Reduce 。Map和Reduce操作需要我们自己定义相应Map类和Reduce类。而 shuffle则是系统自动帮我们实现的,是MapReduce的“心脏”,是奇迹发生的地方。 是其主要流程基本如下图所示: 1、数据的输入   首先,对于MapReduce所要处理的数据,应当存储在分布式文件系统(如HDFS)中,通过使用Hadoop资源管理系统YARN,将MapReduce计算转移到存储有部分数据的机器上。   对于输入数据,首先要对其进行输入分片,Hadoop为 每个输入分片构建一个map任务 ,在该任务中调用map函数对分片中的每条数据记录进行处理。处理每个分片的时间小于处理整个数据所花的时间,因此, 只要合理分片,整个处理过程就能获得很好的负载均衡 。   而关于合理分片,我们不难想到:如果分片数据太大,那么处理所花的时间比较长,整体性能提升不多;反之,如果分片数据切分的太小,那么管理分片的时间和构建map任务的时间又会加大。因此分片要合理,一般情况下,

归并排序算法

China☆狼群 提交于 2020-01-30 16:00:29
@Adrian 图示过程: (1)归并排序流程: (2)合并两个有序数列的过程: # include <stdio.h> # include <stdlib.h> //自定义合并两个有序数列的过程 int merge ( int r [ ] , int s [ ] , int x1 , int x2 , int x3 ) { int i , j , k ; i = x1 ; //第一部分开始的位置 j = x2 + 1 ; //第二部分开始的位置 k = x1 ; while ( ( i <= x2 ) && ( j <= x3 ) ) { if ( r [ i ] <= r [ j ] ) { s [ k ] = r [ i ] ; i ++ ; k ++ ; } else { s [ k ] = r [ j ] ; j ++ ; k ++ ; } } while ( i <= x2 ) { //当x2+1~x3部分比较完了,x1~x2范围内未比较部分的数顺次加到数组r中 s [ k ++ ] = r [ i ++ ] ; } while ( j <= x3 ) { //将x2+1~x3范围内未比较的数顺次加到数组r中 s [ k ++ ] = r [ j ++ ] ; } return 0 ; } //归并排序的过程 int merge_sort ( int r [ ] ,