一、基本思想和步骤
1.确定分治点 mid=(left+right)/2。
2.分别对左右子数组进行递归排序。
3.归并,将左右两个数组合二为一。这是归并排序的关键,本质上也是分治的思想。
归并排序中,拆解出来的小问题就是将两个有序数组变成一个有序的大数组。运用双指针算法,分别指向两个子数组的头,取较小者放在新的数组中,指针后移,直到两个指针都指向空。
二、方法和代码
时间复杂度O(nlogn)
#include <iostream>
using namespace std;
int n;
const int N=1e6+10;
int arr[N];
int tmp[N];
void merge_sort(int arr[],int left,int right)
{
if(left>=right)return;
int mid=(left+right)>>1;//就是(left+right)/2;
merge_sort(arr,left,mid);
merge_sort(arr,mid+1,right);
//整体思路就是把这一段子数组的左右两子数组先排好序,然后往下走,如果无法彻底理解递归就不要去强求理解了
int k=0;//tmp的下标
int i=left,j=mid+1;
while(i<=mid&&j<=right)
if(arr[i]<arr[j])tmp[k++]=arr[i++];
else tmp[k++]=arr[j++];
while(i<=mid)tmp[k++]=arr[i++];
while(j<=right)tmp[k++]=arr[j++];
for(int i=left,j=0;i<=right;i++,j++)
arr[i]=tmp[j];//tmp对应arr中的left到right
};
int main()
{ cin>>n;
for(int i=0;i<n;i++)
{
int num;
cin>>num;
arr[i]=num;
}
merge_sort(arr,0,n-1);
for(int i=0;i<n;i++)
cout<<arr[i]<<" ";
return 0;
}