归并排序 MergeSort (设置哨兵)

归并排序

  1. 基本思路
    归并排序使用分治的思想,每次将数据集分为前后两个部分,直到规模缩减为一,开始合并;合并时通过申请的空间,遍历两个子数据集,将每一个数据从小到大插入,最后将临时数据复制回原序列,直到最后一次得到完整的序列。

  2. 算法

MERGE(array, begin1, begin2, end):
	n1 = begin2-beign1
	n2 = end-begin2+1
	temp1[n1+1] = MAX
	temp2[n2+1] = MAX
	for i-n1
			temp1[i] = array[begin1+i]
	for i-n2
			temp[i] = array[begin2+i]
	i=0, j=0
	for begin1-end
			if temp1[i]<temp2[j]
				array[begin1] = temp1[i]
				begin1++
			else
				array[begin1] = temp2[j]
				begin1++

解释:算法中申请了两个临时的数组,temp1,temp2,分步存放当前数据集的前后两部分(注意它们分别多申请了一个空间存放某个最大值,用作哨兵),之后进行循环,将temp中的数据从小到大插回原序列。

MERGESORT (array, begin, end):
	if begin<end:
			mid = (begin+end)/2
			MERGESORT (array, begin, mid)
			MERGESORT (array, mid+1, end)
			MERGE (array, begin, mid+1, end)
			

解释:先递归地分解,然后合并

  1. 复杂度:O(nlogn)

  2. 运行截图
    在这里插入图片描述

  3. 源代码

#include <iostream>
#include <vector>
#include <ctime>
#include <climits>
using namespace std;
//合并 
void Merge(vector<int> &list, int begin1, int begin2, int end);
//归并排序
void MergeSort(vector<int> &list, int begin, int end);
//得到随机序列
void GetRandList(vector<int> &list, int n);
//打印
void Print(const vector<int> &list);

int main(int argc, char** argv) {
	vector<int> list;
	GetRandList(list,20);
	Print(list);
	MergeSort(list,0,list.size()-1);
	Print(list);
	return 0;
}
void Merge(vector<int> &list, int begin1, int begin2, int end)
{
	int n1 = begin2-begin1;
	int n2 = end-begin2+1;
	vector<int> temp1;
	vector<int> temp2;
	temp1.resize(n1+1);
	temp2.resize(n2+1);	
	temp1[n1] = INT_MAX;
	temp2[n2] = INT_MAX;
	for(int i=0;i<n1;i++)
	{
		temp1[i] = list[begin1+i];
	}
	for(int i=0;i<n2;i++)
	{
		temp2[i] = list[begin2+i];
	}
	int i=0;
	int j=0;
	for(int p=begin1;p<=end;p++)
	{
		if(temp1[i]<=temp2[j])
			list[p] = temp1[i++];
		else
			list[p] = temp2[j++];
	}
}

void MergeSort(vector<int> &list, int begin, int end)
{
	if(begin<end)
	{
		int mid = (begin+end)/2;
		MergeSort(list,begin,mid);
		MergeSort(list,mid+1,end);
		Merge(list,begin,mid+1,end);
	}
}

void GetRandList(vector<int> &list, int n)
{
	list.resize(n);
	for(int i=0;i<n;i++)
	{
		list[i] = rand()%n;
	}
}

void Print(const vector<int> &list)
{
	for(int i=0;i<list.size();i++)
	{
		cout<<list[i]<<" ";
	}
	cout<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值