时空复杂度
时间复杂度:O(nlogn) 空间复杂度:O(n) 使用了分治思想优势
1.稳定
归并的时空复杂度非常稳定的,不论是在哪种情况下,归并算法的时间复杂度都不变,2.高效
归并算法计算效率相比其他算法也是非常快的思路图解
分
把一个有n个元素的数组,分成n个有1个元素的数组 然后边比较边合并治
合并子序列 需要将两个已经有序的子序列合并成一个有序序列 双指针依次比较,小的数先进入结果数组,进入后指针后移 直到所有数字都进入结果数组函数组成
1.分离函数
使用递归,将数组分离到原子化 停止递归条件:x>=y,数组段已分离到只有一个元素 这里不开辟新数组来灌装,而是使用两个头尾index序号来表示分出的数组段 将数组段传入合并函数时,也是使用头尾序号的形式void mergesort(int x,int y) //分离函数,参数x和y分别代表要分离数组段的开头和结尾
{
if (x>=y) return; //如果开头≥结尾,说明数组段已分离到只有一个元素,返回,停止分离
int mid=(x+y)/2; //将中间数求出来,用中间数把数列分成两段
mergesort(x,mid); //递归,继续分离分出的上半段
mergesort(mid+1,y); //递归,继续分离分出的下半段
merge(x,mid,y); //分离结束,进行合并函数
}
2.合并函数
由于没有开辟新的数组 需要合并的数组段在原数组序列中是紧挨在一起的,所以用三个参数index可表示两个数组段 第一段:low~mid,第二段:mid+1~high 合并是需要将两个无序数组段合并为一段有序数组 用两个指针 i、j,放在两段序列的开头,比较所指对象,较小的先进入结果数组,然后进入结果的指针后移 使用递归进行合并 结束条件: 两个数组的比较指针i、j 都已移动到数组结尾(i = mid和 j = high) 未达到结束条件就继续递归调用本函数或使用循环void merge(int low,int mid,int high) //归并
//low 和 mid是要合并的第一个数列的开头和结尾,mid+1 和 high是第二个数列的开头和结尾
{
vector<int> ans(n); //用来合并的临时数组,合并完成后灌装进原数组
int i=low,j=mid+1,k=low; //两个比较指针,一个结果输入指针
while (i<=mid && j<=high) //如果两个数列的数都没放完,循环
{
if (a[i]<a[j]) //若后者大于前者
ans[k++]=a[i++]; //后者入答案数组,且后指针与档案指针后移一格
//k++:先赋值,再加一
else //若前者大于前者
ans[k++]=a[j++]; //前者入答案数组,且前指针与档案指针后移一格
} //k++:先赋值,再增加
while (i<=mid) //若一个数列已放完,前数组还没放玩,就把剩下的都塞进结果数组
ans[k++]=a[i++];
while (j<=high) //若一个数列已放完,后数组还没放玩,就把剩下的都塞进结果数组
ans[k++]=a[j++];
for (int i=low;i<=high;i++)
a[i]=ans[i]; //将排好的结果数组灌装入原数组的位置
标签:归并,int,分离,合并,mid,算法,数组,排序,指针
From: https://www.cnblogs.com/jk-2048/p/18029970