归并排序:
采用了分治策略 就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解。
归并的核心思想 将两个有序的数组合并成一个大的有序的数组,通过递归把待排序数组变成完全有序数组。
归并的核心算法就是如何将2个数组合并
算法思想:
将待排序数组一直往下分解直到不可分解为止也就是一个数为一个子数组
然后对这些子数组层层合并(合并里有排序的过程)得到最后的有序数组
分解的过程很简单 就是一直递归向下分解 直到一个元素一组为止
合并原理:
其实就是合并2个有序数组的算法:
首先要有一个临时数组temp 以及2个索引分别指向2个数组的首地址 让2个索引对应的值进行比较 谁对应的值小 把值小的放入temp 然后当前索引++ 再循环比较 肯定会有一个数组索引先到头 在对另一个数组剩下的元素遍历放入temp即可
然后再把合并好的数组放会原数组对应的为止 就算完成此次合并
以 {3,4,6,10} {2,5,7,8} 为例作图给大家演示下:
两个数组索引对应的值进行比较 小的放进临时数组 索引++ 然后继续比较
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 | 4 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 | 4 | 5 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 | 4 | 5 | 6 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 | 4 | 5 | 6 | 7 |
↓ | ↓ | |||||||
3 | 4 | 6 | 10 | 2 | 5 | 7 | 8 |
temp | |||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
此时 其中一个数组索引已经到头了 然后直接对另一个数组剩余元素进行遍历放入temp即可
可能有些童鞋会有疑问为什么剩下的直接放进去就行?
因为2个数组都是有序数组 此数组当前索引对应的值比另一个数组最大值都大 此数组剩余元素值肯定大于另一个数组而且还是从小到大排列的 所以直接放入temp就可以了麻
temp | |||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 |
动图展示:
算法代码:
public class Sort {
public static void main(String[] args) {
int[] a={10,4,6,3,8,2,5,7};
//归并排序
mergeSort(a,0,a.length-1);
}
private static void mergeSort(int[] a, int left, int right) {
if(left<right){
int middle = (left+right)/2;
//对左边进行递归
mergeSort(a, left, middle);
//对右边进行递归
mergeSort(a, middle+1, right);
//合并
merge(a,left,middle,right);
}
}
private static void merge(int[] a, int left, int middle, int right) {
int[] tmpArr = new int[a.length];
int mid = middle+1; //右边的起始位置
int tmp = left;
int third = left;
while(left<=middle && mid<=right){
//从两个数组中选取较小的数放入中间数组
if(a[left]<=a[mid]){
tmpArr[third++] = a[left++];
}else{
tmpArr[third++] = a[mid++];
}
}
//将剩余的部分放入中间数组
while(left<=middle){
tmpArr[third++] = a[left++];
}
while(mid<=right){
tmpArr[third++] = a[mid++];
}
//将中间数组复制回原数组
while(tmp<=right){
a[tmp] = tmpArr[tmp++];
}
}
}