C++归并排序

10 篇文章 1 订阅

C++归并排序

归并排序是建立在归并操作基础上的一种有效的排序算法,采用分治的思想,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表。称为二路归并,归并排序是稳定排序。

归并操作,指是将两顺序序列合并成一个顺序序列的方法。

如:设有数列{6,202,100,301,38,8,1}

初始状态:6,202,100,301,38,8,1

第一次归并:{6,202}{100,301},{8,38},{1}  比较3次

第二次归并:{6,100,202,301},{1,8,38}  比较4次

第三次归并:{1,6,8,38,100,202,301}  比较4次

总共比较次数为:3+4+4=11次

算法步骤:

第一步:申请空间temp(),使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

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

重复步骤三直到某一指针超出序列尾

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

#include <iostream>
#include <string>
#include <algorithm>

typedef long long LL;
LL cnt=0;
using namespace std;
//分别输入数组,数组左边下标,中间下标,右边下标,临时数组    
//合并左边和右边 

void print(LL a[],LL n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
void mergearray(LL a[],LL left,LL mid,LL right,LL temp[]){
	LL i=left,j=mid+1;
	LL m=mid,n=right;
	LL k=0;
	//左边和右边分别进行循环 
	while(i<=m&&j<=n){
		//左边小于右边就存进临时数组 
		if(a[i]<=a[j])
			temp[k++]=a[i++];
		else{
			temp[k++]=a[j++];
			//cnt+=m-i+1;
		}
	}
	//将原始数组存进临时数组, 
	while(i<=m)
		temp[k++]=a[i++];
		for(i=0;i<k;i++)
			a[left+i]=temp[i];
}
//排序 
void mergesort(LL a[],LL left,LL right,LL temp[]){
	if(left<right){
		LL mid=(left+right)/2;
		mergesort(a,left,mid,temp);
		mergesort(a,mid+1,right,temp);
		mergearray(a,left,mid,right,temp);
		print(a,7);
	}
}
bool MergeSort(LL a[],LL n){
	LL *p=new LL[n];
	if(p==NULL)
		return false;
		mergesort(a,0,n-1,p);
		delete []p;
		return true;
}
int main(){
	
	LL a[]={6,202,100,301,38,8,1};
	MergeSort(a,7);
	for(int i=0;i<7;i++){
		cout<<a[i]<<" ";
	}
	 
	return 0;
}

一开始先对左边进行排序

{6,202},100,301,38,8,1

{6,202},{100,301},38,8,1

{6,100,202,301},38,8,1

左边排序完,对右边进行排序

{6,100,202,301},{8,38},1

{6,100,202,301},{1,8,38}

{1,6,8,38,100,202,301}

排序完成。

速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值