归并排序

归并排序

余生长醉 提交于 2020-01-18 02:42:55
归并排序 步骤: 1.分解 2.解决 3.合并 # include <iostream> using namespace std ; void Merge ( int * a , int p , int q , int r ) { int n1 = q - p + 1 ; int n2 = r - q ; int * L = new int [ n1 + 1 ] ; int * R = new int [ n2 + 1 ] ; for ( int i = 0 ; i < n1 ; i ++ ) { L [ i ] = a [ p + i ] ; } for ( int j = 0 ; j < n2 ; j ++ ) { R [ j ] = a [ q + j + 1 ] ; } L [ n1 ] = 1111 ; R [ n2 ] = 1111 ; int i = 0 , j = 0 ; for ( int k = p ; k <= r ; k ++ ) { if ( L [ i ] <= R [ j ] ) { a [ k ] = L [ i ] ; i ++ ; } else { a [ k ] = R [ j ] ; j ++ ; } } delete [ ] L ; delete [ ] R ; } void MergeSort ( int * a , int l ,

[模板][快速排序&归并排序]

久未见 提交于 2020-01-18 01:50:19
不得不说,手写的快排真的好菜。(即使开了随机数...) 快速排序 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; inline int read(); const int Maxn = 100010 ; namespace iNx{ int n; int q[Maxn]; void exchange(int a,int b){ int t=q[a]; q[a]=q[b]; q[b]=t; } void quicksort(int left,int right){ if(left>=right) return ; exchange(left,(rand()%(right-left+1))+left); int key=q[left],i=left,j=right; while(i<j){ while(q[j]>=key&&i<j) j--; if(j>i) q[i++]=q[j]; while(q[i]<=key&&i<j) i++; if(i<j) q[j--]=q[i]; } q[i]=key; quicksort(left,i-1); quicksort(i+1,right); } int main(){ n=read(); int i;

PAT 乙级 1035 插入与归并 (25分)

只谈情不闲聊 提交于 2020-01-17 16:33:24
1035 插入与归并 (25分) 根据维基百科的定义: 插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。 归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。 现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法? 输入格式: 输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。 输出格式: 首先在第 1 行中输出Insertion Sort表示插入排序、或Merge Sort表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。 输入样例 1: 10 3 1 2 8 7 5 9 4 6 0 1 2 3 7 8 5 9 4 6 0 输出样例 1: Insertion Sort 1 2 3 5 7 8 9 4 6 0 输入样例 2: 10 3 1 2 8 7 5 9 4 0 6 1 3 2 8 5 7 4 9 0 6 输出样例 2: Merge

归并排序

我的梦境 提交于 2020-01-17 03:26:40
/*时间复杂度O(nlog2n) 空间复杂度O(n) 将其分成两组前一部分a 和后一半b,设置一个空数组记录,逐个比较数组大小,小的放入记录数组, 利用分治思想逐步分解计算*/ #include <iostream> using namespace std; void paixu(int att[],int ak,int aj) { if(ak==aj) return; int i=ak,s=(ak+aj)/2,attr[10]; paixu(att,ak,s); paixu(att,s+1,aj);//此处注意分段,前一半到s后一段从s+1开始 int j=s+1; int k; for(k=ak;k<=aj;k++)//主要思想,将整个数列分成两部分k来记录调整数列 { if(i<=s && att[i]<=att[j] || j>aj) //判断分成两部分后那个小那个放入,若有一方全部放完,则另一个直接放入基础数列中 { attr[k]=att[i++];//将晓得放入 } else { attr[k]=att[j++]; } } for(k=ak;k<=aj;k++) { att[k]=attr[k]; } } int main(){ int att[10]={1,3,5,7,9,2,4,6,8,0}; paixu(att,0,9); for(int i=0;i<10;i+

十大排序算法之归并排序(Merge Sort)

佐手、 提交于 2020-01-16 15:17:13
把长度为n的输入序列分成两个长度为n/2的子序列 对这两个子序列分别采用归并排序 将两个排序好的子序列合并成一个最终的排序序列 php代码实现: function mergeSort ( $arr ) { $len = count ( $arr ) ; if ( $len < 2 ) { return $arr ; } $middle = $len > > 1 ; $newArr = array_chunk ( $arr , $middle ) ; $A = mergeSort ( $newArr [ 0 ] ) ; $B = mergeSort ( $newArr [ 1 ] ) ; return merge ( $A , $B ) ; } function merge ( $arr_A , $arr_B ) { $len_A = count ( $arr_A ) ; $len_B = count ( $arr_B ) ; $i = 0 ; $j = 0 ; $tmp = [ ] ; while ( $i < $len_A && $j < $len_B ) { if ( $arr_A [ $i ] < $arr_B [ $j ] ) { $tmp [ ] = $arr_A [ $i ] ; $i ++ ; } else { $tmp [ ] = $arr_B [ $j ] ;

常用的十大排序算法,经典图解版,『精』!!!

倾然丶 夕夏残阳落幕 提交于 2020-01-16 08:33:26
前言 本文或许是东半球分析十大排序算法最好的一篇文章,配有 70 张图片和动画,和你一起一步步看懂排序算法的运行过程。 预计阅读时间 47 分钟,强烈建议先收藏然后通过电脑端进行阅读。 No.1 冒泡排序 冒泡排序无疑是最为出名的排序算法之一,从序列的一端开始往另一端冒泡(你可以从左往右冒泡,也可以从右往左冒泡,看心情),依次比较相邻的两个数的大小(到底是比大还是比小也看你心情)。 冒泡排序动图演示 图解冒泡排序 以 [ 8,2,5,9,7 ] 这组数字来做示例,上图来战: 从左往右依次冒泡,将小的往右移动 冒泡排序1 首先比较第一个数和第二个数的大小,我们发现 2 比 8 要小,那么保持原位,不做改动。位置还是 8,2,5,9,7 。 指针往右移动一格,接着比较: 冒泡排序2 比较第二个数和第三个数的大小,发现 2 比 5 要小,所以位置交换,交换后数组更新为:[ 8,5,2,9,7 ]。 指针再往右移动一格,继续比较: 冒泡排序3 比较第三个数和第四个数的大小,发现 2 比 9 要小,所以位置交换,交换后数组更新为:[ 8,5,9,2,7 ] 同样,指针再往右移动,继续比较: 冒泡排序4 比较第 4 个数和第 5 个数的大小,发现 2 比 7 要小,所以位置交换,交换后数组更新为:[ 8,5,9,7,2 ] 下一步,指针再往右移动,发现已经到底了,则本轮冒泡结束,处于最右边的

Poj2299(归并排序)

亡梦爱人 提交于 2020-01-16 02:30:32
归并排序 1.数组从0开始用 2.二分为(l+1<r) 3.cnt+=mid+j-k-1; 4.递归meger(0,n,a) #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const ll nil=20000000000; const int maxn=500000+10; ll L[maxn/2],R[maxn/2]; int n; ll a[maxn]; ll megersort(int l,int r,int mid,ll a[]){ int n1=mid-l; int n2=r-mid; ll cnt=0; int i,j; for (i=0;i<n1;i++) L[i]=a[l+i]; for (j=0;j<n2;j++) R[j]=a[mid+j]; L[n1]=nil; R[n2]=nil; i=j=0; for (int k=l;k<r;k++){ if(L[i]<=R[j]){ a[k]=L[i++]; } else { a[k]=R[j++]; cnt+=mid+j-k-1; } } return cnt; } ll meger(int l,int r,ll a[]){ if(l+1<r){ int mid=(l

POJ2299 Ultra-QuickSort(归并排序求逆序数)

允我心安 提交于 2020-01-15 06:35:27
归并排序求逆序数 Time Limit: 7000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Description 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 output 0 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

MergeSort(归并排序)原理及C++代码实现

房东的猫 提交于 2020-01-14 19:39:11
归并排序利用分治策略进行排序。原理如下 分解:分解待排的n个元素的序列成个具n/2个元素的两个子序列。 解决:使用归并排序递归地排序两个子序列。 合并:合并两个已排序的子序列以产生已排序的答案。 归并排序的时间复杂度是θ(nlgn)。 归并排序是稳定排序之一。 归并排序不是原址排序,在合并阶段需要申请额外的数组空间。 代码如下: 1 void MergeSort(int * const begin, int * const end) { 2 if (begin + 1 >= end) 3 return ; 4 int m = (end - begin) / 2; 5 MergeSort(begin, begin + m); 6 MergeSort(begin + m, end); 7 Merge(begin, begin + m, end); 8 } 1 //不使用哨兵的版本,需判断边界条件 2 void Merge(int * const first, int * const mid, int * const last) { 3 vector<int> left(first, mid); 4 vector<int> right(mid, last); 5 6 int i = 0, j = 0, k = 0; 7 while (i != left.size() && j !=

第10章 归并排序

对着背影说爱祢 提交于 2020-01-14 18:37:55
【归并】 归并(Merging) :是指将两个或两个以上的有序序列合并成一个有序序列。若采用线性表(无论是那种存储结构)易于实现,其时间复杂度为O(m+n) 。 归并思想实例:两堆扑克牌,都已从小到大排好序,要将两堆合并为一堆且要求从小到大排序。 将两堆最上面的抽出 (设为 C 1 C_1 C 1 ​ , C 2 C_2 C 2 ​ ) 比较大小,将小者置于一边作为新的一堆 (不妨设 C 1 C_1 C 1 ​ < C 2 C_2 C 2 ​ );再从第一堆中抽出一张继续与 C 2 C_2 C 2 ​ 进行比较,将较小的放置在新堆的最下面; 重复上述过程,直到某一堆已抽完,然后将剩下一堆中的所有牌转移到新堆中。 【排序思想】 ① 初始时,将每个记录看成一个单独的有序序列,则 n n n 个待排序记录就是 n n n 个长度为 1 1 1 的有序子序列; ② 对所有有序子序列进行两两归并,得到 ⌈ n 2 ⌉ \lceil \frac{n}{2} \rceil ⌈ 2 n ​ ⌉ 个长度为 2 2 2 或 1 1 1 的有序子序列——一趟归并; ③ 重复② ,直到得到长度为 n n n 的有序序列为止。 上述排序过程中,子序列总是两两归并,称为2-路归并排序。其核心是如何将相邻的两个子序列归并成一个子序列。设相邻的两个子序列分别为: { R [ k ] , R [ k + 1 ] ,