归并排序

《大话数据结构》常见排序算法总结(一)

北城余情 提交于 2019-12-07 22:01:53
文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.04.06 lutianfei none V1.1 2016.07.19 lutianfei 增加了快速排序算法 排序 外排序:需要在内外存之间多次交换数据才能进行 内排序: 插入类排序 直接插入排序 希尔排序 选择类排序 简单选择排序 堆排序 交换类排序 冒泡排序 快速排序 归并类排序 归并排序 排序方法 平均情况 最好情况 最坏情况 辅助空间 稳定性 冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定 简单选择排序 O(n^2) O(n^2) O(n^2) O(1) 稳定 直接插入排序 O(n^2) O(n) O(n^2) O(1) 稳定 希尔排序 O(nlogn)~O(n^2) O(n^1.3) O(n^2) O(1) 不稳定 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 快速排序 O(nlogn) O(nlogn) O(n^2) O(logn)~O(n) 不稳定 测试工程说明 下文都是用以下测试用例进行测试 public static void main (String[] args) { int [] A = new int [] { 11 , 2 , 3 , 22 ,

Hadoop mapreduce原理学习

半世苍凉 提交于 2019-12-07 13:09:52
MapReduce模式结构图: 细化图: 最近整了很长一段时间才了解了map reduce的工作原理, shuffle是mapreduce的心脏,了解了这个过程,有助于编写效率更高的mapreduce程序和hadoop调优 。自己画了一幅流程图(点击查看全图): 另外,还找到一篇文章,很好,引用一下。 Hadoop 是 Apache 下的一个项目,由 HDFS 、 MapReduce 、 HBase 、 Hive 和 ZooKeeper 等成员组成。其中, HDFS 和 MapReduce 是两个最基础最重要的成员。 HDFS 是 Google GFS 的开源版本,一个高度容错的分布式文件系统,它能够提供高吞 吐量的数据访问,适合存储海量( PB 级)的大文件(通常超过 64M ),其原理如下图所示: 采用 Master/Slave 结构。 NameNode 维护集群内的元数据,对外提供创建、打开、删除 和重命名文件或目录的功能。 DatanNode 存储数据,并提负责处理数据的读写请求。 DataNode 定期向 NameNode 上报心跳, NameNode 通过响应心跳来控制 DataNode 。 InfoWord 将 MapReduce 评为 2009 年十大新兴技术的冠军。 MapReduce 是大规模数据 ( TB 级)计算的利器, Map 和 Reduce

归并排序算法总结

元气小坏坏 提交于 2019-12-07 08:10:08
归并排序 //"mergeSort.h" #pragma once #ifndef MERGESORT_MERGESORT_H #define MERGESORT_MERGESORT_H #include<algorithm> void mergeSort(int arr[], int n); void merge(int arr[], int l, int r); //对arr[l, mid]、arr[mid+1, r]两个区间进行归并 void __merge(int arr[], int l, int mid, int r); #endif //"mergeSort.cpp" #include "mergeSort.h" void mergeSort(int arr[], int n) { merge(arr, 0, n - 1); } void merge(int arr[], int l, int r) { if (l >= r) return; int mid = l + (r - l) / 2; merge(arr, l, mid); merge(arr, mid + 1, r); __merge(arr, l, mid, r); } void __merge(int arr[], int l, int mid, int r) { int *aux = new int

排序算法之——归并排序和快速排序

最后都变了- 提交于 2019-12-06 10:59:24
冒泡排序、插入排序、选择排序这三种算法的时间复杂度都为 \(O(n^2)\) ,只适合小规模的数据。今天,我们来认识两种时间复杂度为 \(O(nlogn)\) 的排序算法——归并排序(Merge Sort)和快速排序(Quick Sort),他们都用到了 分治思想 ,非常巧妙。 1. 归并排序(Merge Sort)? 1.1. 归并排序算法实现 归并排序 的核心思想其实很简单,如果要排序一个数组,我们先把数组从中间分成前后两部分,然后分别对前后两部分进行排序,再将排好序的两部分数据合并在一起就可以了。 归并排序使用的是分治思想,分治也即是分而治之,将一个大问题分解为小的子问题来解决。分治算法一般都是用递归来实现的。 分治是一种解决问题的处理思想,递归是一种编程技巧 。 如果要对数组区间 [p, r] 的数据进行排序,我们先将数据拆分为两部分 [p, q] 和 [q+1, r],其中 q 为中间位置。对两部分数据排好序后,我们再将两个子数组合并在一起。当数组的起始位置小于等于终止位置时,说明此时只有一个元素,递归也就结束了。 递推公式: merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r)) 终止条件: p >= r 不用再继续分解 对两个子数组进行合并的过程如下所示,我们先建立一个临时数组

数据结构之内外排序

喜你入骨 提交于 2019-12-06 06:59:06
一、内排序 排序类别 排序方法 最好时间复杂度 平均时间复杂度 最坏时间复杂度 辅助空间 稳定性 备注 插入类 插入 O(n) O(n 2 ) O(n 2 ) O(1) 稳定 大部分已排序时较好 希尔排序 - O(n s ),1<s<2 - O(1) 不稳定 s是所选分组 交换类 冒泡排序 O(n) O(n 2 ) O(n 2 ) O(1) 稳定 n小时较好 快速排序 O(nlogn) O(nlogn) O(n 2 ) O(logn) 不稳定 n大时较好 选择类 选择 O(n 2 ) O(n 2 ) O(n 2 ) O(1) 不稳定 n小时较好 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 n大时较好 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 n大时较好 基数排序 O(d(n+rd)) O(d(n+rd)) O(d(n+rd)) O(rd) 稳定 见下文 1.插入排序(InsertSort) 插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的

数据结构与算法-归并排序

懵懂的女人 提交于 2019-12-06 02:18:25
原理: 分解过程 : 存在序列A[1...n],将这个序列分解成俩个序列(↓(n/2)向下取整为m),一边含m个数元素序列A[1...m],一边n-m个数元素序列A[m+1...n]; 合并过程 : 针对俩个序列A的俩个子序列A[p...q],A[q+1...s],而且A[p...q],A[q+1...s]都是各自排序好的序列,现在合并得到一个A[p...s]排序好的子序列; 停止分解 : 序列中只有一个元素时,那么这个序列就是有序序列,可以停止分解过程; 归并排序 : 递归分解、合并过程(递归结束判断就是序列中元素只有一个); 合并过程的伪代码: 合并序列A的俩个子序列A[p...q],A[q+1...s]且都是已经排序好的子序列 设置∞为元素的最大值 MERGE(A , p , q , s) { // 为了方便表示给A[p...q],A[q+1...s]赋值L和R序列 L[1...q-p+1] = A[p,q]; R[1...s-q]= A[q+1,s] ; // 分别给L和R序列设置一个最大值 L[q-p] = ∞; R[s+1] = ∞; // 定义俩个变量存储L和R中元素的位置 i = 1; j = 1; for(k = p; k<= s; k++) { if(L[i] <= R[j]){ A[k] = L[i] i++; } else { A[k] = R[j]; j+

java实现快速排序,归并排序

十年热恋 提交于 2019-12-05 20:44:53
//1.快速排序 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for(int i=0;i<n;i++) { a[i] = sc.nextInt(); } qsort(a,0,n-1); for(int i=0;i<n;i++) { System.out.print(a[i]+" "); } sc.close(); } private static int getPos(int[] a,int left,int right) { int mid = a[right]; while(left<right) { while(left<right && a[left]<=mid) { left++; } a[right] = a[left]; while(left<right && a[right]>=mid) { right--; } a[left] = a[right]; } a[left] = mid; return left; } private static void qsort(int[] a,int

经典排序算法

随声附和 提交于 2019-12-05 08:34:10
  排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序。 O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序。 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。 关于稳定性: 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。 名词解释: n:数据规模 k:“桶”的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 冒泡排序   冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

归并排序

瘦欲@ 提交于 2019-12-05 07:26:18
简介: 归并排序的时间复杂度为O( n log n ),是一种速度仅次于快速排序的稳定排序算法。 (题外话:虽然C++的STL中有sort()函数,但有些算法题用到了归并排序的思想,如求逆序数,因此归并排序是必须懂的。当然,网上关于归并排序的讲解很多,这里仅仅只是给出模板。) 模板: 1 void mergeArray(int *a,int l,int mid,int r,int *temp) 2 { 3 int i=l,j=mid+1; 4 int k=0; 5 6 while(i<=mid&&j<=r) 7 { 8 if(a[i]<=a[j]) 9 temp[k++]=a[i++]; 10 else 11 temp[k++]=a[j++]; 12 } 13 14 while(i<=mid) 15 temp[k++]=a[i++]; 16 while(j<=r) 17 temp[k++]=a[j++]; 18 19 for(int i=0;i<k;i++) 20 a[l+i]=temp[i]; 21 } 22 23 void mergeSort(int *a,int l,int r,int *temp) 24 { 25 if(l<r) 26 { 27 int mid=(l+r)/2; 28 mergeSort(a,l,mid,temp); 29 mergeSort(a,mid+1

归并排序的实现

此生再无相见时 提交于 2019-12-05 07:06:43
都在注释里了: import java.util.Arrays; public class MergeSort { public static void main(String[] args) { int[] a = {2,1,13,10,5,3,8,8,4,9,4}; mergeSort(a); //非递归就用这句 //recuSort(a,0,a.length-1); //递归就用这句 System.out.println(Arrays.toString(a)); } public static void mergeSort(int []a) { //非递归,复杂些 int length = a.length; int len = 1; //len 表示左边len个,右边len个做归并。起始为1,即两两归并 while(len < length) { for(int i = 0;i + len < length;i = i + (len << 1)) { //对于每个归并单位,从0开始,直到开始归并的下标+归并单位的值超过最大下标 int low = i; //每次归并的开始总是i int mid = i + len - 1; //一定要在这里计算mid,不能用high和low算,因为个数为奇数时high是截取的 int high = low + (len << 1) - 1;