2019.12.2--2019.12.8第三周 归并排序

基本原理

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
时间复杂度:O(nlog(2)n)
基本思想:分治
(我知道上面这一串说不清楚,所以还是上图吧)
在这里插入图片描述
图片来源 — https://baike.sogou.com/v8340582.htm?fromTitle=%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
如图所示:
不断分解——分别排序——边比较边合并——得到有序数列

具体流程

参数说明:start 为前部分第一个元素的下标,mid为前部分结尾,end为后一部分结尾

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
void merge(ll a[],ll start,ll mid,ll end)//用于合并两数组时不断比较
{
	ll i,j,k;//分别指示两部分和临时数组的元素到了哪一个,可理解为指向所用元素的指针,在不断后移
	ll *b = (ll *)malloc((end-start+1)*sizeof(ll));//设置一个临时空间,用于存储两数组合并后的状态。
	i=start;
	j=mid+1;
	k=0;
	while(i<=mid&&j<=end)
	{
		if(a[i]<a[j])	b[k++]=a[i++];
		else			b[k++]=a[j++];	
	}	
	while(i<=mid)	b[k++]=a[i++];
	while(j<=end)	b[k++]=a[j++];
	for(i=0;i<k;i++)	a[i+start]=b[i];
	free(b);
}

void sort(ll a[],ll start,ll end)//不断分割原数组
{
	ll mid=(start+end)/2;
	if(a==NULL||start>=end)	return;
	sort(a,start,mid);
	sort(a,mid+1,end);	//分别对两边继续分割
	merge(a,start,mid,end);
} 

int main()
{
	ll a[8]={10,6,7,1,3,9,4,2};
	sort(a,0,7);
	for(int i=0;i<8;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}
  1. 第一步:进入sort函数,递归将数组分割,再将其两部分继续分割,这样无限分割下去,直至start>=end,即每个部分中只余一个元素
  2. 第二步:进入merge函数
    (我再也不想画图了)

    依次排序得到数组b,然后将b数组的值返回给a数组,释放b的空间。
    依次合并的过程,可用如下图解(不是这道题,但很清楚)
    在这里插入图片描述
  3. 得到运行结果,输出a数组得1 2 3 4 5 6 7 9 10
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值