ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

归并排序

2022-08-22 14:01:09  阅读:139  来源: 互联网

标签:归并 递归 int 数组 排序 指针


1. 归并排序——分治

# 算法原理

归并排序的思想就是分治,先递归分解数组,再合并数组。

将数组分解到最小之后,再往上一层两两合并两个有序的数组,最终递归返回的就是一个排好序的数组。

递归分解的时间复杂度是O(logn),合并数组的时间复杂度是O(n),因此归并排序的时间复杂度就是O(nlogn)

# 步骤

  1. 确定分界点
    • mid = (l + r) / 2
  2. 递归调用左右区间
    • 一层层调用到底,从最底层归并
  3. 归并排序, 合二为一

# 如何实现合二为一?

合并的基本思路就是双指针算法,比较两个数组最前面的数字,谁小就先取谁,取了后相应的指针就往后移动一位。 然后再比较,直到一个数组为空,最后把一个数组的剩余部分复制过来即可。

  1. 找两个指针中较小的一个数,把值写入res[],然后指针右移
  2. 直到其中一个序列的指针指向最后一个
  3. 把另一个序列的指针剩下的数依次写入res[]

# 代码模板

const int N = 10e5 + 10;
int temp[N];
void merge_sort(int q[], int l, int r)
{
    if(l >= r) return;
    int mid = (l + r) >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);
    int i = l, j = mid + 1, k = 0;
    while(i <= mid && j <= r) {
        if( q[i] <= q[j] ) temp[k++] = q[i++];
        else temp[k++] = q[j++];
    }
    while(i <= mid) temp[k++] = q[i++];
    while(j <= r) temp[k++] = q[j++];
    for(i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];
}

# 总结

归并排序没有太多复杂的边界问题,核心思想是分治,只要理解了这一点,基本上原理就弄清楚了。

在进行归并排序之前,先递归调用左右区间,可以理解为将数组二分分解。

调用到最深一层也就是区间里只有一个元素的时候,开始执行递归函数的返回,也就是执行归并的过程。

归并的过程可以如上图所示,每一层的都是把2个相邻的区间通过双指针算法排序并合并到一个区间(合并这个动作由递归返回发生),每次递归返回时区间都是有序的,最终合并回一个区间,完成排序。

需要注意的是,归并排序的时间复杂度是O(nlogn),但是中间过程需要用到一个数组来存放临时排序的结果,所以空间复杂度是O(n)。

2022.4.10

标签:归并,递归,int,数组,排序,指针
来源: https://www.cnblogs.com/Ethan-Code/p/16612583.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有