一.归并排序原理(Wikipedia)

  归并排序本质是分治思想的应用,并且各层分治递归可以同时进行

  1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

  2.设定两个指针,最初位置分别为两个已经排序序列的起始位置

  3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  4.重复步骤3直到某一指针到达序列尾

  5.将另一序列剩下的所有元素直接复制到合并序列尾

二.过程

原始数据

seg = 1时

我的算法参考的是wikipedia上的算法,与VisuAlgo上所示的稍有区别,VisuAlgo上是先2个数字合并,然后合并成4个有序数列,然后在对后面的2个合并,在合并成4个有序数列,把这两组有序数列合并成一个长度为8的有序数列。

wikipedia上,是先将所有的单个数字合并成有序的长度为2的有序数组,然后在将所长度为2的分别合并成长度为4的有序数组,循环知道合成长度为Len的有序数组。个人认为wikipedia上的方法更加容易表达,因为不用回退可以一次性处理完所有相同长度的数据。

wikipedia上代码的排序过程如图所示:

3.代码(参考了wikipedia上的代码,只需要第一次分配一次空间)

 #include <iostream>
#include <vector>
#include <algorithm>
using namespace std; template <typename T>
void MergeSort( vector<T> & nums ) {
int seg = ;
int len = nums.size();
vector<T> CopyNums(nums);
for(int seg = ; seg < len; seg += seg ){
for(int start = ; start < len; start += seg + seg ){
int low = start;
int mid = min( start + seg, len );//对于最后一次归并
int high = min( start + seg + seg, len );//最后一次归并长度会大于len
int k = low;
int start1 = low;
int end1 = mid;
int start2 = mid;
int end2 = high;
while( start1 < end1 && start2 < end2 ){
CopyNums[k++] = nums[start1]<nums[start2]? nums[start1++]:nums[start2++];
}
while( start1 < end1 ){
CopyNums[k++] = nums[start1++];//如果start1后还有元素没有归并,则将start1后的元素进行归并
}
while( start2 < end2 ){
CopyNums[k++] = nums[start2++];////如果start2后还有元素没有归并,则将start2后的元素进行归并
}
}
nums.swap(CopyNums);//在C++ STL中,耗时是常量,因为实际并没有交换他们的值,而只是交换了指针。
//(i.e., the containers exchange references to their data, without actually performing any element copy or movement) }
} int main(){
vector<int> nums{,,,,,,,,,,,,,,};
cout<<" Before Sort:" ;
for( auto m: nums){
cout << m <<" ";
}
cout<<endl;
MergeSort( nums );
cout<< " After Sort:";
for( auto m: nums){
cout << m <<" ";
}
cout<<endl;
}

4.总结

1.空间复杂度,因为只有开始分配了一次与原始数据相同长度的空间,所以空间复杂度为O(n);

2.时间复杂度,总的比较次数在(nlogn)/2和nlogn-n+1之间;

3.归并排序是稳定的排序算法。

排序算法总结(二)归并排序【Merge Sort】的更多相关文章

  1. 排序算法二:归并排序(Merge sort)

    归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是O(nlgn). (一)算法实现 private void merge_sort(int[] array, int ...

  2. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  3. 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)

    连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...

  4. Java排序算法(二)

    java排序算法(二) 二.改进排序算法 2.1希尔排序 定义:希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. ...

  5. java讲讲几种常见的排序算法(二)

    java讲讲几种常见的排序算法(二) 目录 java讲讲几种常见的排序算法(一) java讲讲几种常见的排序算法(二) 堆排序 思路:构建一个小顶堆,小顶堆就是棵二叉树,他的左右孩子均大于他的根节点( ...

  6. [Swift]八大排序算法(二):快速排序

    排序分为内部排序和外部排序. 内部排序:是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 外部排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存 ...

  7. java排序算法(二):直接选择排序

    java排序算法(二) 直接选择排序 直接选择排序排序的基本操作就是每一趟从待排序的数据元素中选出最小的(或最大的)一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完,它需要经过n- ...

  8. 【DS】排序算法之冒泡排序(Bubble Sort)

    一.算法思想 冒泡排序是排序算法中比较有意思的一种排序方法,也很简单.其算法思想如下: 1)比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2)对每一对相邻元素作同样的工作,从开始第一对到结尾 ...

  9. 小小c#算法题 - 8 - 归并排序 (Merging Sort)

    “归并”的含义是将两个或两个以上的有序序列组合成一个新的有序序列.这个“归并”可以在O(n+m)的数量级上实现,但这同时也需要O(n+m)的空间复杂度.具体为:首先分配一个新的长度为n+m的空序列,然 ...

  10. 【排序算法】冒泡排序(Bubble Sort)

    一.简介 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换, ...

随机推荐

  1. Controller方法的返回值

    方法的返回值1.ModelAndView这个就不多说,这是最基础的,前面定义一个ModelAndView,中途使用addObject方法添加属性,再返回.视图解析器会自动扫描到的.2.String这个 ...

  2. python版恶俗古风自动生成器.py

    python版恶俗古风自动生成器.py """ python版恶俗古风自动生成器.py 模仿自: http://www.jianshu.com/p/f893291674c ...

  3. python解无忧公主的数学时间编程题001.py

    python解无忧公主的数学时间编程题001.py """ python解无忧公主的数学时间编程题001.py http://mp.weixin.qq.com/s?__b ...

  4. iOS程序进入后台后仍运行定时器NSTimer

    由于本应用需要在应用进入后台后还要进行定时的检测功能,因此对于我来说怎样让APP在进入后台后 保持运行状态是比较大的需求.然后在iOS系统中是很难实现的,不管是 通过 音频还是 定位系统,我查找了一些 ...

  5. rpm软件包管理/yum软件管理

    绝大数开源软件都是公布源代码的,源代码一般被打包为tar.gz归档压缩文件,然后手工编译为二进制可执行文件 ./configure 检查编译环境/相关库文件/配置参数,生成makefile make ...

  6. .net 找回密码的第一步 第二步 第三步的进程条

    先写一个div作为存放这个进程条的容器 开始写js 根据jQuery选择器找到需要加载ystep1的容器 loadstep方法可以初始化 steps参数表示步骤名称,content则是鼠标移动到当前位 ...

  7. oracle删除数据库中的所有数据的拼接语句

    create or replace function count_rows/**查询各表实际记录数*/(table_name in varchar2,owner in varchar2 default ...

  8. 使用树莓派和kali Linux打造便携式渗透套件

    在DIY前你需要: .树莓派Raspberry Pi Model B+型 或者 树莓派2代; .充电宝 X1; .USB WIFI网卡 X1; .8G SD卡 X1; .Raspberry PI触摸显 ...

  9. 一个简单的tr:hover效果

    昨天,搞项目的时候,在一个小问题上卡了40分钟,现在想想,还是平时比较少去注意一些细节,经过这次,一定要去多注意细节了. 好了废话不多说,我现在说明下遇到的问题,一个表格中,要求是当鼠标滑过每一行时, ...

  10. Unity3d Web Player 与server端联网配置

    针对Unity3d Web Player 的server端联网配置写一随笔咯.  以SmartFoxServer2X官方的Unity3d Example ”tris“为例,部署好服务器之后,在Unit ...