归并排序及模板

归并排序理解

归并排序的主要操作如下:
(1)分解。把初始序列分成长度相同的左、右两个子序列,然后把每个子序列再分成更小的两个子序列,直到子序列只包含一个数。这个过程用递归实现。
(2)求解子问题,对子序列排序。最底层的子序列只包含一个数,其实不用排序。
(3)合并。归并两个有序的子序列,这是归并排序的主要操作。比如下面举例,把a[ ]分成两个子序列,比较后存进b[ ],假设两个子序列已经分别排好序。
过程如下(有点丑…将就一下):

在这里插入图片描述
在这里插入图片描述

只要有一个子序列结束,就可以把另一个子序列后面的都放进去,因为是排好序的

归并排序的时间复杂度:对n个数进行排序:

  • 需要log2(n)趟归并。

在这里插入图片描述

  • 在每一趟归并中有很多次合并操作。共需O(n)次比较。所以时间复杂度为

在这里插入图片描述

归并排序模板

输入n个数,对n个数进行排序。

#include<iostream>

using namespace std;

const int N=1e6 + 10;

int n;
int q[N],temp[N];
void merge(int q[],int l,int r)
{
	if(l >= r) return;//满足条件不再往下进行
	
	int mid = (l + r)/2;
	
	merge(q,l,mid),merge(q,mid+1,r);//左右分开递归 
	
	int k=0,i=l,j=mid+1;//k表示temp里个数,i指向左子序开头,j指向右子序开头 
	while(i <= mid && j<= r)
		if(q[i] <= q[j]) temp[k++]=q[i++];
		else temp[k++]=q[j++];
	while(i <= mid) temp[k++ ]=q[i++ ];//若左半边没循环完 全部拿出来 
	while(j <= r) temp[k++ ] = q[j++ ];//若右半边没循环完 全部拿出来 
	
	for(i = l,j = 0;i <= r;i++,j++) q[i]=temp[j];//把temp排好的赋给q[] 
} 

int main()
{
	cin>>n;
	for(int i = 0;i < n; i++) cin>>q[i];
	
	merge(q,0,n-1);//从0~n-1
	
	for(int i = 0;i < n; i++) cout<<q[i]<<" ";
	
	return 0;
} 
发布了67 篇原创文章 · 获赞 216 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45895026/article/details/104134503