合并排序(2-路归并排序)算法总结

合并排序是目前已知稳定的速度最快的排序算法,时间复杂度可以达到O(nlogn),所以很有必要做一次笔记进行总结,而且很多语言中排序方法采用的就是合并排序.

合并排序中心思想是采用两个变量分别标记左右,left和right,在 left到left+size size+1到right之间不断采用分治法,相邻的不断进行比较,不断增加size的大小,最终达到剩余数字数量少于2*size为最终目的,也标志着合并排序的结束。


步骤:

1.首先size为1,每两个比较一次,保证每两个都是顺序的

2.增加size为原来二倍,通过移动指针不停地进行比较排序

3.循环,直到size超过N代表所有的都排序过了


时间复杂度分析:

由于是基本顺序的比较排序,所以每次合并需要O(n)时间。每次需要执行(logn)次合并

所以算法MergeSort需要O(nlogn)的时间


C++代码:

//合并排序
#include "iostream"
#include "cstdlib"
#include "ctime"
#include <windows.h>
using namespace std;

template<class Type>
void MergeSort(Type source[], int n)
{
Type *dest = new Type[n];
int size = 1;
while(size < n){
MergePass(source, dest, size, n);//合并到数组dest中,每次排序一次后size增加一次
size += size;
MergePass(dest, source, size, n);//再合并回source中
size += size;
}
}

template<class Type>
void MergePass(Type source[], Type dest[], int size, int n)
{
int left = 0;
while(left <= n - 2 * size){
//合并为大小为s的相邻2段子数组
Merge(source, dest, left, left+size-1, left+2*size-1);
left = left+2*size;
}
//剩下的元素少于2s个
if((left+size) < n)
Merge(source, dest, left, left+size-1, n-1);
else
for(int j = left;j <= n-1; j++)
dest[j] = source[j];
}

template<class Type>
void Merge(Type source[], Type dest[], int left, int mid,int right)
{//两个标志不断移动
int i = left, j = mid+1, k = left;
while((i <= mid) && (j <= right))
if(source[i] <= source[j])
dest[k++] = source[i++];
else
dest[k++] = source[j++];
if(i > mid)
for(int q = j; q <= right; q++)
dest[k++] = source[q];
else 
for(int q = i; q<= mid; q++)
dest[k++] = source[q];
}


template<class Type>
void creat(Type source[], int n)
{
srand((unsigned)time(NULL));
for(int i = 0;i < n; i++)
source[i] = rand()%(n*n+50);
}


void main()
{
DWORD TimeStart=GetTickCount();//以毫秒为单位记录时间"windows.h"
int n = 1000;
int *unsort = new int[n];
creat(unsort, n);
MergeSort(unsort, n);
for(int i = 0;i < n; i++)
cout<<unsort[i]<<endl;
DWORD TimeEnd=GetTickCount();
TimeEnd -= TimeStart;
cout<<TimeEnd;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值