一.归并排序原理(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. linux 用户、组,修改文件权限

    文件权限 -rwxrw-r‐-1 root root 1213 Feb 2 09:39 abc - 10个字符确定不同用户能对文件干什么 - 第一个字符代表文件(-).目录(d),链接(l) - 其余 ...

  2. JS 验证一组input框是否为空的方法

    function checkInput() { var $tr = $("#tb_confirmed .scrollContent").find("tr"); ...

  3. hdoj-2033

    A+B系列: #include "stdio.h"int main(){ int a[3],b[3],c[3],i,n,j,flag; while(~scanf("%d& ...

  4. 5分钟学习maven(根据英文文档整理)

    英文原地址:http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html 一.前提 需要懂得如何在计算机上安装软件 ...

  5. BZOJ 1954 The xor-longest Path

    问题转化为一些数里面选两个数异或和最大. #include<iostream> #include<cstdio> #include<cstring> #includ ...

  6. 【LeetCode】Rotate Array

    Rotate Array Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = ...

  7. java作业5

    (一)用你的大数类实现加和减两个功能(乘除阶乘未实现) import java.util.Scanner; import java.io.IOException; import java.io.Inp ...

  8. WPF Step By Step 控件介绍

    WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...

  9. this的指向及应用

    this的指向: //this 指的是调用 当前方法 (函数) 的那个对象 function fn1(){ this; } //fn1(); this => window //obj.oncli ...

  10. beta 阶段的 postmortem 报告

    part一: 用户数:目前约30人 总结:与当初的预算差不多,首先1.第一次开发软件,经验效率不足,那是很正常的事情.2.用户数量少,因为宣传力度还是比较的少.应该加强软件的推广才行. part二: ...