归并排序

C 归并排序算法

两盒软妹~` 提交于 2019-12-02 06:37:41
代码如下 #include <iostream> #include <cstddef> void __merge(int arr[], int begin, int mid, int end) { int n1 = mid - begin; int n2 = end - mid; int* A = new int[n1 + 1]{}; int* B = new int[n2 + 1]{}; A[n1] = INT_MAX; B[n2] = INT_MAX; int i = 0; for (; i < n1; i++) A[i] = arr[i + begin]; int j = 0; for (; j < n2; j++) B[j] = arr[j + mid]; i = j = 0; int k = begin; for (; k < end; k++) { if (A[i] <= B[j]) arr[k] = A[i++]; else arr[k] = B[j++]; } delete[] A; delete[] B; } void merge_sort(int arr[], int length) { if (length > 1) { int mid = length / 2; merge_sort(arr, mid); merge_sort(arr + mid,

【算法学习】归并排序

为君一笑 提交于 2019-12-02 00:18:49
1.算法思路:   (1)将待排序数组分为两份,利用递归将两份数组排好序   (2)将两个有序数组归并成一个有序数组。       实现方法:         a.设置两个指针,分别指向两个数组的开头,比较指针所指向的数字,将较小的数字加入一个辅助数组中,指针前移,直到其中一个指针溢出         b.将未溢出的数组剩余的元素加入辅助数组中         c.将辅助数组整体拷贝到原来的数组中 2.代码(JAVA): public class mergesort{ public static void mergeSort(int[] arr, int l, int r) { if(l<r){ int mid=l+(r-l)/2; mergeSort(arr,l,mid); mergeSort(arr,mid+1,r); merge(arr,l,r); } } public void merge(int[] arr,int l,int r){ int[] tmp=new int[r-l+1]; int mid=l+(r-l)/2;int p1=l; int p2=mid+1; int i=0; while(p1<=m&&p2<=r){ if(arr[p1]<arr[p2]) tmp[i++]=arr[p1++]; else tmp[i++]=arr[p2++]; } while

归并排序

别说谁变了你拦得住时间么 提交于 2019-12-01 20:11:19
归并排序 思路 1.归并排序采用了分而治之的策略 2.首先向将整个序列两两划分,在递归地分别对这个序列的左边和右边两两划分,这样直到最小序列为单个元素 3.之后再序列与序列之间两两归并成有序的序列,直到整个序列有序 示意图 拆分序列 合并相邻有序的子序列 转载自https://www.cnblogs.com/chengxiao/p/6194356.html 代码实现 package sort; import java.util.Arrays; public class MergeSort { public static void main(String[] args) { // TODO Auto-generated method stub int[] a= {10,9,8,7,6,5,4,3,2,1}; int[] result=new int[a.length]; System.out.println(Arrays.toString(a)); mergeSort(a, result, 0, a.length-1); System.out.println(Arrays.toString(a)); } public static void mergeSort(int[] a,int[] result,int start,int end) { if(start>=end) {

归并排序和快速排序

删除回忆录丶 提交于 2019-12-01 17:02:57
def merge_sort(arr): if len(arr) == 1: return arr p = 0 n = len(arr) q = (p+n)//2 return merge(arr, merge_sort(arr[p:q]), merge_sort(arr[q:])) def merge(arr, arr1, arr2): temp = list() i = j = 0 for r in range(len(arr)): if i < len(arr1) and j < len(arr2): # <= 保证稳定性 if arr1[i] <= arr2[j]: temp.append(arr1[i]) i += 1 else: temp.append(arr2[j]) j += 1 else: if i < len(arr1): temp.extend(arr1[i:]) else: temp.extend(arr2[j:]) return temp def quick_sort(arr): if len(arr) <= 1: return arr privot = arr[0] larr, rarr = partition(arr[1:], privot) return quick_sort(larr) + [privot] + quick_sort(rarr)

从0开始学算法--排序(1.5归并排序)

≡放荡痞女 提交于 2019-12-01 12:50:08
算法理解:   一个数组长度为n,他的前m个元素是升序的,后n-m个元素升序的,怎么使整个数组变成一个升序数组? 如n=6,m=3 1 3 5 2 4 6 1 2 3 4 5 6 排序前 排序后 #include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <cmath> #include <queue> using namespace std; const int maxn=1e5+1; int A[maxn]; int T[maxn];//辅助数组。 int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%d",&A[i]); } int p=0,q=m,i=0; while(p<m||q<n){ if(q>=n||(p<m&&A[p]<=A[q]))T[i++]=A[p++]; else T[i++]=A[q++]; } for(int i=0;i<n;i++){ A[i]=T[i]; } for(int i=0;i<n;i++){ printf("%d ",A[i]); } printf("\n"); return 0; }

排序算法 - 归并算法

我只是一个虾纸丫 提交于 2019-12-01 07:15:40
在实际应用当中,对于数据较大的输入,归并排序是比较快的一个算法。该算法采用的是分治法的思想。 原理 :将数据分开排序,然后进行合并,最后形成一个排好的序列。 将其合并输出,如下图所示: 代码实现如下: /** * 归并排序 * * @author Deters * @date 2019/10/12 */ public class MergeSort { /** * 归并 */ private static void merge(Integer[] array, int start, int end, int middle) { // 临时数组,储存左右分支合并之后的数组 Integer[] temp = new Integer[end - start + 1]; // 临时数组当前位置下标 int index = 0; // 左分支下标 int lCt = start; // 右分支下标 int rCt = middle + 1; // 当左右分支都有数据时 while (lCt <= middle && rCt <= end) { temp[index++] = array[lCt] - array[rCt] < 0 ? array[lCt++] : array[rCt++]; } // 只有左分支有数据 while (lCt <= middle) { temp[index++]

归并排序详解

时间秒杀一切 提交于 2019-12-01 04:56:40
浅谈归并排序 排序算法有很多,今天让我说一说: 冒泡选择和插入,希尔基数和堆桶; 还有快排很好写,STL大法没得说。 还有一个叫归并,时间稳定不爆锅。 —— 一个会说相声的博主的引言 相比于一些复杂度不太稳定的排序算法(比如快排,最坏的时候会退化成 \(O(n^2)\) 级别的)或者时间稳定但是本来就是 \(O(n^2)\) 级别的(汗),归并排序的好处就是将时间复杂度妥妥地控制在 \(O(nlogn)\) 级别,在数据量很大的情况下会比 \(O(n^2)\) 算法快很多。但是我们在设计程序的时候,的确一般都用快排(因为码量少,STL,退化的概率实在是很低)。所以归并排序在这个时候显得很是鸡肋。但是为了更高远的目标(用归并排序来理解分治思想,二分手段),或者了解一下归并排序的小技巧,还是非常有用的。 归并排序的概念 归并排序,顾名思义就是一种 “递归合并” 的排序方法(这个理解很重要)。对于一个数列,我们把它进行二分处理,依次递归下去,然后将小范围的数进行排序,最后将其合并在一起。就实现了归并排序。 这实际上是运用了 分治思想 ,显然,想要把一个数列排好序,最终达到的目的就是它的任何一部分都是有序的。这样的话,我们可以考虑分别把数列分成N多个部分,让每个部分分别有序,然后再将其统一,变成所有的东西都有序。这样就实现了排序。这个想法就叫分治思想。 语言总是无力的

归并排序

折月煮酒 提交于 2019-12-01 04:51:54
归并排序 思路 1.分解:分解待排序的 \(n\) 个元素的序列成各具 \(n/2\) 个元素的俩哥哥子序列 2.解决:使用归并排序递归的排序两个子序列 3.合并:合并两个已排序的子序列得到答案 合并 先考虑将两个已排序好的数组合并为一个数组 伪代码如下: MERGE(A, p, q, r) //合并数组A[p..q],A[q+1..r] n1 = q - p + 1 n2 = r - q let L[1..n1+1] and R[1..n2+1] be new array for i = 1 to n1 L[i] = A[p+i-1] for j = 1 to n2 R[j] = A[q+j-1] L[n1+1] = INFINITY //设置哨兵元素 R[n2+1] = INFINITY //设置哨兵元素 i = j = 1 for k = p to r if L[i] <= R[j] A[k] = L[i] i = i + 1 else A[k] = R[j] j = j + 1 解决 将MERGE作为归并排序的一个子程序调用,下面的过程MERGE_SORT,排序子数组$A[p..r] $中的元素。若 $p \geq r $, 则该子数组最多有一个元素,则已经排好序,否则,分解步骤简单的计算一个下标 \(q\) ,将 \(A[p, r]\) 分成两个子数组 \(A[p, q]

归并排序(Merge sort)

那年仲夏 提交于 2019-12-01 00:35:51
定义 归并排序采用分治策略进行比较操作排序,将待排序的n个元素分解为个含n/2个元素的两部分,使用递归或其它方式迭代地两个子序列进行同样的排序操作,然后合并两个已排序的子序列。 分析 序列的划分 序列的划分较为简单直接,n为奇数时两部分长度相差1,可以规定将较长的一部分作为第二部分的长度。 序列的合并 从最基本的合并开始,如果划分到一个子序列仅有一个元素时,不能进一步划分,对该子序列的归并排序会直接返回,对应于n=1时的归并排序,是直接求解的不需要进行归并操作。当单元素子序列归并排序完成时,将两个子序列进行合并得到两个元素的子序列,对应于n=2时的归并排序就完成了,以此类推,不失一般性考虑如何合并任意大小的两个已排序子序列的问题。 对于序列的划分操作需要进行*lg*n次,每次都需要对n个元素进行合并操作,而合并本身也是对两个有序子序列的再排序,合并的开销必须尽可能地小,至少需要将所有子序列遍历一遍,其渐进复杂度下界是Ω(n)。如果采用原址排序的方式,由于两个子序列除了自身是有序的,两者之间没有任何联系,这会是一个一般性的排序问题。因此,为了利用已排序的子序列,将两者复制后依次进行比较并合并回原序列中。 实现 def merge_sort(A, start, end): if end - start <= 1: return mid = (end + start) / 2 merge

归并排序(Merge sort)

六月ゝ 毕业季﹏ 提交于 2019-12-01 00:16:56
定义 归并排序采用分治策略进行比较操作排序,将待排序的n个元素分解为个含n/2个元素的两部分,使用递归或其它方式迭代地两个子序列进行同样的排序操作,然后合并两个已排序的子序列。 分析 序列的划分 序列的划分较为简单直接,n为奇数时两部分长度相差1,可以规定将较长的一部分作为第二部分的长度。 序列的合并 从最基本的合并开始,如果划分到一个子序列仅有一个元素时,不能进一步划分,对该子序列的归并排序会直接返回,对应于n=1时的归并排序,是直接求解的不需要进行归并操作。当单元素子序列归并排序完成时,将两个子序列进行合并得到两个元素的子序列,对应于n=2时的归并排序就完成了,以此类推,不失一般性考虑如何合并任意大小的两个已排序子序列的问题。 对于序列的划分操作需要进行*lg*n次,每次都需要对n个元素进行合并操作,而合并本身也是对两个有序子序列的再排序,合并的开销必须尽可能地小,至少需要将所有子序列遍历一遍,其渐进复杂度下界是Ω(n)。如果采用原址排序的方式,由于两个子序列除了自身是有序的,两者之间没有任何联系,这会是一个一般性的排序问题。因此,为了利用已排序的子序列,将两者复制后依次进行比较并合并回原序列中。 实现 def merge_sort(A, start, end): if end - start <= 1: return mid = (end + start) / 2 merge