归并排序

C#各种排序算法代码实现

被刻印的时光 ゝ 提交于 2020-03-06 11:48:49
转自: https://blog.csdn.net/sniper007/article/details/53080131 排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。 将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。 分类 稳定排序:假设在待排序的文件中,存在两个或两个以上的记录具有相同的关键字,在用某种排序法排序后,若这些相同关键字的元素的相对次序仍然不变,则这种排序方法是稳定的。其中冒泡,插入,基数,归并属于稳定排序,选择,快速,希尔,堆属于不稳定排序。 就地排序:若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间为O(1),则称为就地排序。(百度百科) 冒泡排序 已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1

归并排序(MergeSort)

夙愿已清 提交于 2020-03-06 11:45:49
//版权所有 Anders06 于2007年10月25日 归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。 1、 基本思想 ( 1 ) 分治法的基本思想 分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 ( 2 ) 归并排序的基本基本步骤 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 分解 : 讲n个元素分成n/2 个元素的子序列 解决 : 用合并并排序对两个子序列递归地排序 (在对子序列排序时,长度为1时递归结束) 合并 : 合并两个已经排好序的子列序以得到排序结果 以扑克牌为例, 假设有两堆牌面朝上地放在桌上,每一堆都是排好序的,最小的牌在最上面。我们希望将两堆牌合并成升序的一堆牌。基本步骤包括在面朝上的两堆牌中,选择顶上两张较小的一张,将其取出放入到输出堆,重复此动作,知道有一堆为空为止,然后吧另一堆所剩下的牌面朝下放入到输出堆即可。 合并排序的时间为 O(n). 2、 算法分析 ( 1 )时间复杂度 Merge过程运行的时间为O(n),

“擂台比武式”的归并算法

我怕爱的太早我们不能终老 提交于 2020-03-05 05:39:03
一. 关于“擂台比武” 假设现在有一堆人要进行擂台比武,他们的战斗力如下: [5, 1, 6, 3, 4, 2, 8] 数字越小代表战斗力越强 现在采用抽签模式,两两对决,胜者进入下一轮( 如果奇数,单独人员可直接晋级 ),情况如下: 那么,如何把所有人的战斗力排名算出来呢? 二. 归并算法 如同擂台比武, 先拆分 成分各组,直到细分为单个,开始比较 后合并 注意点: 拆分的时候要注意奇偶数的问题 合并的时候要注意比较排序,当一个数组排序完成,另外一个要把剩余的全部补充 三. 代码示例 /** * @author yanghao * @version MergeTest.java, v 0.1 2020-03-02 15:10 */ public class MergeTest { public static void main ( String [ ] args ) { Integer [ ] data = { 5 , 1 , 6 , 3 , 4 , 2 , 8 } ; data = sort ( data ) ; for ( int i = 0 ; i < data . length ; i ++ ) { System . out . print ( data [ i ] + " = " ) ; } } private static Integer [ ] sort (

归并排序与快速排序模板与图解笔记(转载)

ⅰ亾dé卋堺 提交于 2020-03-04 07:20:10
https://blog.csdn.net/zpznba/article/details/83745205 C++ 归并排序与快速排序 2018年11月05日 15:15:31 zpznba 阅读数 948 归并排序: 【算法逻辑】 归并的思路(分治)是把一个大问题a拆解成两个小问题b和c,解决了两个子问题再整合一下,就解决了原问题。用递归的方法,先分解再合并(分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突): 【代码实现】 # include <iostream> using namespace std; void Merge ( int arr[], int l, int q, int r){ int n=r-l+ 1; //临时数组存合并后的有序序列 int* tmp= new int[n]; int i= 0; int left=l; int right=q+ 1; while(left<=q && right<=r) tmp[i++] = arr[left]<= arr[right]?arr[left++]:arr[right++]; while(left<=q) tmp[i++]=arr[left++]; while(right<=r) tmp[i++]=arr[right++]; for( int j= 0;j<n;++j) arr[l+j]=tmp

数据结构-快速排序 归并排序

£可爱£侵袭症+ 提交于 2020-03-03 16:03:46
文章目录 归并排序 (Merge sort) 简介 代码 性能分析 快速排序(Quick sort) 简介 代码 性能分析 排序算法的结合 总结 注:所有的代码在我的 Github 中有均具体C++代码实现。 这里主要讲的是时间复杂度为O(nlogn)的两种排序算法:快速排序(Qiuck sort)和 归并排序 (Merge sort)。 这两种排序都是用了分治的思想,我们因此可以借鉴这个思想来解决非排序的一些问题,例如: 如何在O(n)的时间复杂度内查找一个无序数组中的第K大的元素? 归并排序 (Merge sort) 简介 简单地说,如果要排序一个数组,我们首先吧数组从中间分成前后两个部分,然后对前后两个部分分别排序,最后将排序好的两部分进行合并。 这里使用了分治的思想,也就是分而治之,将一个大问题分成几个小的子问题来解决,小的问题解决了,大的问题也就解决了。 这里,主要就是merge函数的实现问题了, merge(A[p...r], A[p...q], A[q+1...r]) 也就是将已经有序的 A[p...q] 和 A[q+1...r] 合并成一个有序的数组,这里我们使用了一个额外的临时数组,其空间带下为 r - p + 1 ,具体操作如下: 代码 void merge(int arr[], int l, int m, int r) { int n = r - l + 1;

归并排序——MergeSort实现(Java)

蓝咒 提交于 2020-03-02 17:52:57
根据大佬们的一些构思和做法,自己实现了归并算法,总体利用递归实现,空间消耗的还是比较大,mergesort方法的空间复杂度就在O(N). package 数据结构_排序 ; public class 归并排序 { public static void main ( String [ ] args ) { int [ ] arr = { 1 , 8 , 36 , 5 , 2 , 4 , 6 } ; MergeSort sort = new MergeSort ( ) ; sort . mergeSort ( arr , 0 , arr . length - 1 ) ; for ( int i : arr ) { System . out . print ( i + " " ) ; } } } class MergeSort { /** * * @param a add a list of need sort * @param start where you start sorting * @param end where you end sorting */ public void mergeSort ( int [ ] a , int start , int end ) { //当拆分至最后一个停止拆分,否则递归拆分 if ( start < end ) { int mid = (

快速排序与归并排序

独自空忆成欢 提交于 2020-03-01 20:56:40
快速排序与归并排序 快速排序 快速排序又称”快排”。排序思路:给定一个数组,选定一个分区点pivot,使得小于等于pivot的元素放在左边,大于pivot放在右边,递归使得区间为1那么排序已经是从小到大了。 递归公式:quick_sort(p,q) = quick_sort(p,r-1) + quick_sort(r+1,q)满足p>=q则终止。 代码实现 /** * @Author : zzz * @Date : Created in 16:25 2020/2/22 * @Description : TODO */ public class SortDemo { private int [ ] arr = new int [ ] { 2 , 5 , 3 , 6 , 8 , 1 , 4 , 7 , 10 , 9 } ; public static void main ( String [ ] args ) { SortDemo sort = new SortDemo ( ) ; //快速排序 sort . quick_sort ( ) ; } public void print ( int [ ] a ) { for ( int i = 0 ; i < a . length ; i ++ ) { System . out . print ( a [ i ] + " " ) ; }

归并排序

痞子三分冷 提交于 2020-03-01 03:05:47
描述: 归并排序就是将两个或两个以上有序表合并成一个有序表的过程。将两个有序表合并成一个有序表的过程称为2-路归并,下面以2-路归并为例其排序过程是: 假设初始序列有n个元素,则可看成n个长度为1有序子序列,然后两两归并,得到 ⌈ n / 2 ⌉ \lceil n/2 \rceil ⌈ n / 2 ⌉ (向上取整,大于等于n/2的最小整数)个长度为2或1(奇数个元素剩个元素单独成列)的有序子序列;再两两归并,如此重复,直到得到一个长度为n的有序序列为止。 其中两个有序子序列合并成一个序列的过程为:初始两子序列下标都指向首元素,每次都比较两下标元素,小的放入辅助数组并下标后移一位,直至其中一个数组全部完成比较,将另一个数组剩下的元素全部放进辅助数组。 java代码 import java . util . Arrays ; public class MergeSort { // 外部调用接口 public static void mergeSort ( int [ ] arr ) { // 避免递归过程中频繁开辟空间,开始建一个长度的等于原数组长的临时数组 int [ ] temp = new int [ arr . length ] ; sort ( arr , 0 , arr . length - 1 , temp ) ; } private static void sort (

插入排序和归并排序

心不动则不痛 提交于 2020-03-01 02:24:39
插入排序 一共有三种:直接插入排序、希尔排序和折半插入排序。最后一个折半插入排序,感觉用在数组上面不太方便,就没写出来。 递归实现没有思路,使用的非递归算法。 直接插入排序 这个算法默认前n个数是已经排好序的,n随着你的插入逐渐变大,最开始是1。 然后从后往前逐渐查找应该插入的位置;我的算法是从小到大,那就依次对比当前位置的值是否比要插入的值大,如果大就往后移动一个位置,小于等于当前位置的值就进行插入结束这一次的插入操作,进入下一次。 希尔排序 这个排序算法的思路就是将数组分为好多组,然后逐渐减少,最终只剩下一组,就是最终的结果。 最开始将数组根据初始增量分为两两一组,在每一组内进行排序;逐渐缩短增量,直到增量为一,就是排好序的数组。 在组内排序的算法其实可以是别的算法。 折半插入排序 和直接插入排序思路相同,但是在查询插入点的时候,是从已经排好序的数组中间查询要插入的点,查询到之后将插入点之后的数依次后移,将数插入。 归并排序 数组从大依次切开,分为n组,然后再将相邻的两组进行合并,并排序,最后只剩下一组就是结果。这个算法使用递归会比较简单点。非递归实现,没思路。 代码 package 算法设计与分析 ; public class Work3 { public Work3 ( ) { int [ ] nums = { 2 , 3 , 8 , 4 , 5 , 7 , 1 , 9 ,

[转]海量数据处理的面试题的方法总结

喜你入骨 提交于 2020-02-29 16:36:20
处理海量数据问题,无非就是: 分而治之/hash映射 + hash统计 + 堆/快速/归并排序; Bloom filter/Bitmap; Trie树/数据库/倒排索引; 外排序; 分布式处理之hadoop/mapreduce。 本文接下来的部分,便针对这5种方法模式结合对应的海量数据处理面试题分别具体阐述。 密匙一、分而治之/hash映射 + hash统计 + 堆/快速/归并排序 1、海量日志数据,提取出某日访问百度次数最多的那个IP。 既然是海量数据处理,那么可想而知,给我们的数据那就一定是海量的。针对这个数据的海量,我们如何着手呢?对的,无非就是分而治之/hash映射 + hash统计 + 堆/快速/归并排序,说白了,就是先映射,而后统计,最后排序: 分而治之/hash映射:针对数据太大,内存受限,智能是:把大文件化成(取模映射)小文件,即16字方针:大而化小,各个击破,缩小规模,逐个解决 hash统计:当大文件转化了小文件,那么我们便可以采用常规的hashmap(ip,value)来进行频率统计。 堆/快速排序:统计完了之后,便进行排序(可采取堆排序),得到次数最多的IP。 具体而论,则是: “首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法,比如模1000