赞
踩
学习视频:acwing算法基础课
目录
基本思想:分治
1.确定分界点mid=(l+r)/2 : 数组将数组要排序的 l到r的部分分为 l到(l+r)/2 和 (l+r)/2+1到r 两组
2.递归排序left部分,right部分
3.归并:把两个有序的数组合为一个有序的数组
实现方法:假设两个有序数组为a[ ],b[ ],用一个新数组temp[ ]来记录答案
此时数组a,b已经排好序,所以i,j指针指向的数为数组a,b中最小的数。比较a[i],b[j],选其中较小的值放入temp数组,若相等则可任选一个放入。这里假设a[i]较小,则将a[i]的值放入temp数组,i右移一位
再次比较a[i],b[j],将较小的值放入temp数组,并让此指针后移一位,循环比较,直到有一指针到终点
假设i指针先到达终点,跳出循环,再将b数组j指针所指及之后的部分放到temp数组里
a[i]<b[j],所以a[i]放入temp,i指针后移一位
b[j]<a[i],b[j]放入temp,j指针后移一位
b[j]<a[i],b[j]放入temp,j指针后移一位
b[j]=a[i],这里设相等时将a数组中的数放入temp数组,所以a[i]放入temp数组,i指针后移一位
b[j]<a[i],b[j]放入temp,j指针后移一位
b[j]=a[i],a[i]放入temp数组(这里设相等时将a数组中的数放入temp数组),i指针后移一位
b[j]<a[i],b[j]放入temp,j指针后移一位
a[i]<b[j],所以a[i]放入temp,i指针后移一位
a[i]<b[j],所以a[i]放入temp,i指针后移一位,但是i指针已经指到a数组末尾无法后移,跳出循环
此时a指针已经遍历完毕,应将b数组从j指针开始遍历,将j指针及之后的所有数放入temp数组;从j指针开始的所有数只有一个12,所以将12放入temp,最后temp为2 3 5 6 6 8 8 9 10 12
- #include<iostream>
- using namespace std;
-
- const int N = 100005;//数组最大存储量
- int q[N], temp[N], n;//q为待排序数组 temp为暂时保存答案的数组 n为待输入数组个数
-
- //归并排序
- void merge_sort(int l, int r)//l和r为待排序区间的两端
- {
- if (l == r) return;//当l与r重合时返回(此时数组只有一个数字)
- int mid = (l + r) / 2;//求mid
- merge_sort(l, mid);//排序l到mid
- merge_sort(mid + 1, r);//排序mid+1到r
-
- int i = l, j = mid + 1, t = 0;
- while (i <= mid && j <= r)//将待排序区间分为两个区间l到mid和mid+1到r
- {
- //谁小就将谁放入temp
- if (q[i] < q[j]) temp[t++] = q[i++];
- else temp[t++] = q[j++];
- }
-
- //哪个数组没遍历完就遍历哪个数组
- while (i <= mid) temp[t++] = q[i++];
- while (j <= r) temp[t++] = q[j++];
-
- //将排完序的数组放回原数组
- for (int i = l, t = 0; i <= r; i++, t++)
- {
- q[i] = temp[t];
- }
- }
-
- int main()
- {
- cin >> n;
- for (int i = 0; i < n; i++)
- {
- cin >> q[i];
- }
-
- merge_sort(0, n - 1);
-
- for (int i = 0; i < n; i++)
- {
- cout << q[i] << " ";
- }
-
- return 0;
- }
输入n 及数组元素
断点放在merge_sort()调用这一句,merge_sort函数调用,传入参数merge_sort(0,6)
进入merge_sort函数(为了方便以下简称ms函数)并继续运行到ms函数再次调用之前
此时l=0,r=6,mid=3
调用ms(0,3)并继续运行到ms函数再次调用之前
此时l=0,r=3,mid=1
调用ms(0,1)并继续运行到ms函数再次调用之前
此时l=0,r=1,mid=0
调用ms(0,0) 此时l=0,r=0,l==r 所以返回
调用ms(1,1) 此时l=1,r=1,l==r 所以返回
继续向下运行,此时l=0,r=1,mid=0;令i=l=0,r=mid=1
将区间0到1分为了 区间left:下标0 和 区间right:下标1
进入while循环比大小
q[i]:q[0]=6 q[j]:q[1]=8 q[i]<q[j] 所以temp[t]:temp[0]=6
i++后i=1,i>mid 所以跳出while循环
此时区间right还没遍历
所以遍历区间right
temp[1]=q[1]=8
跳出while循环
通过for循环将temp数组的数放回原数组
放回原数组后函数结束 返回上一级调用
调用ms(2,3)
接下来就是重复的过程 就不一一列举啦
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。