基础算法-归并排序

 基本思想-分治:将一个大问题分解成若干个小问题,分别解决这些小问题,然后将结果合并起来,最终得到整个问题的解

1.确定分界点mid,为整个数组的中间点。

2.递归排序left & right。它是一个承诺,承诺当这个递归调用返回时,你会得到一个已经排好序的子数组。而这个承诺的兑现,完全依赖于第三步的归并操作。

3.从树的最底部归并,即合二为一。此步骤时间复杂度为O(n),因为每个元素都被比较了一次。

其中第3步“合二为一”:

1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

2.设定两个指针,最初位置分别为两个已经排序序列的起始位置;

3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

4.重复步骤 3 直到某一指针达到序列尾;

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

归并算法代码如下:
#include <iostream>
using namespace std;

const int N=1e6+10;//全局变量不在栈上分配,而是在内存的数据区,有充足的空间大小 
int n;
int q[N];
int tmp[N];
void merge_sort(int q[],int l,int r)
{
	if(l>=r) return;
	
	int mid=(l+r)/2;
	
	merge_sort(q,l,mid);
	merge_sort(q,mid+1,r);
	
	int k=0;int i=l;int j=mid+1;
	while(i<=mid&&j<=r)
	{
		if(q[i]<=q[j]) tmp[k++]=q[i++];
		else tmp[k++]=q[j++];
	}
	while(i<=mid) tmp[k++]=q[i++];
	while(j<=r) tmp[k++]=q[j++];
	
	for(i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%d",&q[i]);
	
	merge_sort(q,0,n-1);
	
	for(int i=0;i<n;i++)
	printf("%d ",q[i]);
	
	return 0;
}

归并排序是稳定排序。

时间复杂度为O(nlogn),不存在分情况好坏。

posted @ 2026-01-31 16:34  波澜不惊某纸  阅读(1)  评论(0)    收藏  举报