归并排序是基本排序之一,主要用到分治的基础算法思想,刚入坑的小伙伴可能会不太理解,望这篇简陋的题解能够帮助大家,如果有什么问题或者想法欢迎大家在评论区讨论。
#include<bits/stdc++.h>
///万能头文件
using namespace std;
const int MAXN = 100005;
typedef long long ll;
ll a[MAXN],b[MAXN], cnt;
void Merge(ll l,ll mid,ll r)///合并,分为左边界,中间点,右边界
{
ll i=l,j = mid + 1, t = 0;///左边界从l开始,遍历到中间点,右边界从mid+1开始到r
while(i<=mid&&j<=r){
if(a[i]>a[j]){
b[t++] = a[j++];///将小数a[j]排入
//补充:当题目有求逆序对个数的cnt += mid - i + 1;
}
else b[t++] = a[i++];///即a[i]<a[j]把小数a[i]加入到b数组中
}
while(i<=mid) b[t++] = a[i++];///把剩下排好序的数加入到b数组中防止漏掉数
while(j<=r) b[t++] = a[j++];///同理
for(i=0;i<t;i++) a[l+i] = b[i];///赋值回原来的数组,方便打印
}
void Mergesort(ll l,ll r)
{
if(l<r){///将每个序列不断二分,直到每个元素成为单独的序列
ll mid = (l+r)/2;///中间数
Mergesort(l,mid);///分治思想先将左部分排序
Mergesort(mid+1,r);///将右部分排序
Merge(l,mid,r);///合并序列
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];///输入
Mergesort(1,n);///传入的为左右边界
for(int i=1;i<=n;i++)cout<<a[i]<<' ';///输出
}