归并排序

PTA乙级1035,插入与归并

久未见 提交于 2019-11-28 21:56:42
分析:参考柳婼的代码 # include <bits/stdc++.h> using namespace std ; int main ( ) { int n , a [ 100 ] , b [ 100 ] , i , j ; cin >> n ; for ( int i = 0 ; i < n ; i ++ ) cin >> a [ i ] ; for ( int i = 0 ; i < n ; i ++ ) cin >> b [ i ] ; for ( i = 0 ; i < n - 1 && b [ i ] <= b [ i + 1 ] ; i ++ ) ; //将i指向满足从小到大的最后一个下标 for ( j = i + 1 ; a [ j ] == b [ j ] && j < n ; j ++ ) ; //遍历b[j] if ( j == n ) { //插入排序中未排序的序列顺序不变 cout << "Insertion Sort" << endl ; sort ( a , a + i + 2 ) ; //对后一个元素加入前面已排序的序列中进行排序 } else { cout << "Merge Sort" << endl ; int k = 1 , flag = 1 ; while ( flag ) { flag = 0 ; for ( i = 0 ; i < n

5.1-分治-归并排序

ⅰ亾dé卋堺 提交于 2019-11-28 21:54:49
数组排序任务可以如下完成: 1)把前一半排序 2) 把后一半排序 3) 把两半归并到一个新的有序数组,然后再拷贝回原数组,排序完成。 #include<iostream> using namespace std; void MergeSort(int a[], int s, int e, int tmp[]); void Merge(int a[], int s, int m, int e, int tmp[]); const int maxn = 10000; int a[maxn]; int b[maxn]; int main(){ int n; cin >> n; for (int i = 0; i < n; i++){ cin >> a[i]; } MergeSort(a, 0, n - 1, b); for (int i = 0; i < n; i++) cout << a[i] << " "; cin.get(); cin.get(); return 0; } void MergeSort(int a[], int s, int e, int tmp[]){ if (s < e){ int m = s + (e-s) / 2; MergeSort(a, s, m, tmp); MergeSort(a, m+1, e, tmp); Merge(a, s, m, e,

排序算法--归并排序算法解析

社会主义新天地 提交于 2019-11-28 21:46:00
一、归并算法理解 在理解归并排序算法之前,我们先了解一下,什么是归并算法。 一次归并运算的动画示意图,如下: 如动画所示,红色虚线为中,将列表分成左右两份,且都是元素从小到大的有序列表。两个指针分别指向两份列表头部, 比较两个指针所指元素大小,提取小的元素,并将小的元素指针向右移动。接着继续比较,如此循环,最终形成一个有序的列表。 代码示例: 1 def merge(l,left,mid,right): 2 i = left 3 j = mid +1 4 temp = [] 5 while i <= mid and j <= right:#左右指针都在移动情况 6 if l[i] <= l[j]: 7 temp.append(l[i]) 8 i += 1 9 else: 10 temp.append(l[j]) 11 j += 1 12 while i <= mid: #右指针已经到达右半列表尾部,左指针还没到达。 13 temp.append(l[i]) 14 i += 1 15 while j <= right: #左指针已经到达左半列表尾部,右指针还没到达。 16 temp.append(l[right]) 17 j += 1 二、归并排序算法思路 1、将列表 分解, 直至分成一个元素。 2、一个元素是有序的。 3、通过归并算法,逐层将两个有序列表 归并

算法导论——归并排序

北慕城南 提交于 2019-11-28 21:42:59
#include<stdio.h> #define MAXN 100 //A[p,q] A[q+1,r]是两个有序数组,想办法把他们结合成一个有序数组 void merge(int A[],int p,int q,int r){ int n=0; int i=p; int j=q+1; int tmp[MAXN]; while(i<=q&&j<=r){ if(A[i]<=A[j]) tmp[n++]=A[i++]; else tmp[n++]=A[j++]; } while(i<=q) tmp[n++]=A[i++]; while(j<=r) tmp[n++]=A[j++]; int k; for(k=p;k<p+n;k++) A[k]=tmp[k-p]; } //归并排序主体 void merge_sort(int A[],int p,int r){ if(p<r){ int q=(p+r)/2; merge_sort(A,p,q); merge_sort(A,q+1,r); merge(A,p,q,r); } } int main(){ int A[]={2,56,3,7,86,1,6,43,12}; merge_sort(A,0,8); int k; for(k=0;k<=8;k++) printf("%d ",A[k]); printf("\n"); return 0; }

poj2299(归并排序求逆序对)

坚强是说给别人听的谎言 提交于 2019-11-28 17:32:09
题目链接:https://vjudge.net/problem/POJ-2299 题意:给定一个序列,每次只能交换邻近的两个元素,问要交换多少次才能使序列按升序排列。 思路:本质就是求逆序对。我们用归并排序求逆序对,这也是简单的cdq分治。 #include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> using namespace std; typedef long long LL; const int maxn=5e5+5; int n,a[maxn],tmp[maxn]; LL ans; void merge_sort(int l,int r){ if(l==r) return; int mid=(l+r)>>1; int t1=l,t2=mid+1,cnt=l; merge_sort(l,mid); merge_sort(mid+1,r); while(t1<=mid||t2<=r){ if(t2>r||(t1<=mid&&a[t1]<=a[t2])) tmp[cnt++]=a[t1++]; else{ ans+=(mid-t1+1); tmp[cnt++]=a[t2++]; } } for(int i=l;i<=r;++i) a[i]=tmp[i]; } int main(){ while

归并排序(mergesort)

梦想与她 提交于 2019-11-28 17:29:38
一、算法思路:   分治策略:向量与列表通用     序列一分为二 // O(1)   子序列递归排序 // 2 x T(n/2)   合并有序子序列 // O(n) 二、举例如下:   T(n) = 2*T(n/2) + O(n) T(n) = O(nlog(n)) 利用替换法即可求解;其中O(n)是归并两个已排序子序列的时间。      二路归并merge原理如下所示:    二路归并merge实现如下:   开辟空间B来存储_elem[lo,mi)中的元素,而_elem[mi,hi)的元素并不需要开辟新的空间来缓存,只需要定义一个指针C指向这段内存就可以了。       二路归并的再次改进:   因为C是位于A的后半段,当B完全耗尽时,不需要在执行A[i++] = C[k++]; 所以不需要等待C耗尽,一旦B耗尽,就终止。所以交换循环体内两句的次序,删除冗余逻辑。       二路归并的复杂度: 将j+k作为一个整体来看,最坏情况下,只需要O(n)的线性时间。    来源: https://www.cnblogs.com/ccpang/p/11416256.html

数据结构和算法 (二)

不想你离开。 提交于 2019-11-28 13:48:24
数据结构(swift实现)一 1. 常用数据结构 1. 1 数组 1. 2 字典 1. 3 链表 1. 4 堆栈 1.4.1 堆 1.4.2 栈 1.5 队列 1.5.1 优先队列 1.5.2 循环队列 1.6 树 1.6.1 二叉树 1.6.2 二叉搜索树 1.6.3 平衡二叉树 1.7 图 2. 常用算法 2.1 查找算法 2.1.1 二分查找 2.1.2 广度优先搜索算法 2.1.3 深度优先搜索算法 2.2 排序算法 2.2.1 排序算法简介 2.2.2 排序算法比较 2.2.2.1 稳定性比较 2.2.2.2 时间复杂度比较 2.2.2.3 辅助空间比较 2.2.2.4 其他比较 2.2.3 排序算法实现 2.2.3.1 插入排序 2.2.3.2 选择排序 2.2.3.3 冒泡排序 2.2.3.4 快速排序 2.2.3.5 堆排序 2.2.3.6 归并排序 2.2.3.7 希尔排序 2.2.3.8 二叉树排序 2.2.3.9 计数排序 2.2.3.10 桶排序 2.2.3.11 基数排序 2.2.3.12 1. 常用数据结构 1. 1 数组 1. 2 字典 1. 3 链表 1. 4 堆栈 1.4.1 堆 1.4.2 栈 1.5 队列 1.5.1 优先队列 1.5.2 循环队列 1.6 树 1.6.1 二叉树 1.6.2 二叉搜索树 1.6.3 平衡二叉树 1.7 图 2.

归并排序

大城市里の小女人 提交于 2019-11-28 12:23:06
归并排序 将两个有序的数组归并成一个更大的有序数组。 原地归并的抽象方法 public static void merge(Comparable a[], int lo, int mid, int hi) { int i = lo, j = mid + 1;//两个待归半边并的头 //将代归并的元素放入到aux中 for (int k = lo; k <= hi; k++) { aux[k] = a[k]; } for (int k = lo; k <= hi; k++) { if (i > mid) {//左半边用尽 //取右半边的元素 a[k] = aux[j++]; } else if (j > hi) {//右半边用尽 //取左半边的元素 a[k] = aux[i++]; } else if (less(aux[j], aux[i])) { a[k] = aux[j++]; } else { a[k] = aux[i++]; } } } 该方法先将元素复制到 aux[] 中,然后再归并岛 a[] 中。方法再归并时(第二个 for 循环)进行了 4 个条件判断,分别是: 左半边用尽(取右半边的元素) 右半边用尽(取左半边的元素) 右半边的当前元素小于左半边的当前元素(取右半边的元素) 右半边的当前元素大于等于左边的当前元素(取左半边的元素) 自顶向下递归 分治思想

归并排序求逆序对

做~自己de王妃 提交于 2019-11-28 11:06:43
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; int n, a[100010], tmp[100010]; long long ans; void msort(int left, int right) { if (left == right)return; int mid = (left + right) / 2; msort(left, mid); msort(mid + 1, right); int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (a[i] < a[j]) tmp[++k] = a[i], i++; else tmp[++k] = a[j], j++, ans += mid - i + 1; } while (i <= mid) tmp[++k] = a[i++]; while (j <= right) tmp[++k] = a[j++]; for (int i = 1; i <= k; i++) a[left + i - 1] = tmp[i]; }

【Python实现归并排序】

纵饮孤独 提交于 2019-11-28 10:15:36
原文: http://blog.gqylpy.com/gqy/347 首先,归并排序使用了二分法,归根到底的思想还是分而治之。拿到一个长数组,将其不停的分为左边和右边两份,然后以此递归分下去。然后再将它们按照两个有序数组的样子合并起来。这样说起来可能很难理解,所以 图就来了: 归并排序将数组以中间的值进行拆分,最后分到最细之后再将其使用对两个有序数组进行排序的方法对其进行排序。 两个有序数组排序的方法则非常简单,同时对两个数组的第一个位置进行比大小,将小的放入一个空数组,然后将放入空数组的那个位置的指针往后移一个,然后继续和另外一个数组的上一个位置进行比较,以此类推。到最后任何一个数组先出栈完,就将另外一个数组里的所有元素追加到新数组后面。 递归拆分的时间复杂度是logN,进行两个有序数组排序的方法复杂度是N,所以该算法的时间复杂度是N*logN,即NlogN。 Python代码示例: lst = [2, 5, 7, 8, 9, 1, 3, 4, 6] def merge_sort(lst, low, high): # 不断递归调用自己,直至拆分成单个元素的时候返回这个元素,不再拆分 if low < high: # 取拆分的中间位置 mid = (low + high) // 2 merge_sort(lst, low, mid) # 左 merge_sort(lst, mid