归并排序的定义
归并排序是一种稳定的排序算法,相对其他排序算法而言,是一种速度比较快的算法,时间复杂度为 O ( n × l o g ( n ) ) ,但是需要损耗空间,其空间复杂度为 O ( n ) ,即需要一个额外的数组进行对子数组进行排序。
我们知道排序有很多种,学过了冒泡,对分等排序后,其实还有一种像是冒泡和对分的结合体的排序,归并排序。
归并排序的思想用四个字总结就是—分而治之:
所谓分而治之,就是将一串乱序的数据先按一定的规则切成小块,然后再按一定的顺序进行排列。比如说我们现在有 4 3 2 1四个数,我们就把他们切成两份,43一组,21一组,在两个小组里进行排序是很简单的,得到的结果是34和12,我们再将他们拼合在一起就是1 2 3 4的顺序了。
动画演示
模块解释
合并
这里对应第一个动画效果
void merge(vector<int>&vec,int left,int mid,int right)
{
//定义辅助容器,用来存放合并后的数据
vector<int>helper(right-left+1,0);
int p1 = left,p2 = mid + 1;
int index = 0;
//这里就是比较存放,将小的那一个存放入helper辅助数组内
while(p1<=mid&&p2<=right)helper[index++] = (vec[p1]<vec[p2]?vec[p1++]:vec[p2++]);
//当然,总会有一些数据没有被存放,下面的操作就是将其也存放进去
while(p1<=mid)helper[index++] = vec[p1++];
while(p2<=right)helper[index++] = vec[p2++];
//将helper内整理好的数据重新放回vec容器
for(int i=0;i<helper.size();++i)vec[left+i] = helper[i];
}
拆分
//拆分递归
void mergeSort(vector<int>&vec,int left,int right)
{
//注意,要及时返回ruturn,不能一只无限拆
if(left>=right)return;
//定义mid就是为了将一组数拆成两部分
int mid = left + ((right-left)>>1);
mergeSort(vec, left, mid);
mergeSort(vec,mid+1,right);
merge(vec,left,mid,right);
}
//重载
void mergeSort(vector<int>&vec){
//如果只有一个数据就没有必要排序了
if(vec.size()<2)return;
mergeSort(vec,0,(int)vec.size()-1);
}
总和代码演示
#include<bits/stdc++.h>
using namespace std;
#define gcd __gcd;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x);
void merge(vector<int>&vec,int left,int mid,int right)
{
vector<int>helper(right-left+1,0);
int p1 = left,p2 = mid + 1;
int index = 0;
while(p1<=mid&&p2<=right)helper[index++] = (vec[p1]<vec[p2]?vec[p1++]:vec[p2++]);
while(p1<=mid)helper[index++] = vec[p1++];
while(p2<=right)helper[index++] = vec[p2++];
//将helper内整理好的数据重新放回vec容器
for(int i=0;i<helper.size();++i)vec[left+i] = helper[i];
}
//拆分递归
void mergeSort(vector<int>&vec,int left,int right)
{
if(left>=right)return;
int mid = left + ((right-left)>>1);
mergeSort(vec, left, mid);
mergeSort(vec,mid+1,right);
merge(vec,left,mid,right);
}
//重载
void mergeSort(vector<int>&vec){
if(vec.size()<2)return;
mergeSort(vec,0,(int)vec.size()-1);
}
int main(){
vector<int>vec;
int n,x;
scanf("%d",&n);
rep(i, 1, n){
scanf("%d",&x);
vec.push_back(x);
}
mergeSort(vec);
rep(i, 0, n-1){
if(i!=n-1)cout << vec[i] << " ";
else cout << vec[i] << endl;
}
return 0;
}
相关图片来源自[黑暗主宰的博客],侵必删(https://blog.csdn.net/engineerhe/article/details/104065282)