这篇文章我们来讲一下十大排序中的归并排序。
目录
1.概述
2.代码实现
3.总结
1.概述
归并排序主要是运用了归并的思想。
下面具体的来讲一下归并排序的整个流程和思想。
首先,给你一个无序的数组,要求你对它进行归并排序。归并排序首先需要将这个数组拆分成一个个的元素,怎么拆?折半拆。你知道数组的首个元素的索引,知道其最后一个元素的索引,所以你就知道其中间元素的索引,这样就将数组一分二了,然后对前半部分来说,首元素的索引没变,尾元素的索引变为了中间索引,对于后半部分来说,首元素的索引变为中间元素的索引加1,尾元素的索引没变。然后前半部分又分为了两部分,后半部分又分为了两部分,就这样一直递归下去。什么时候结束?当首元素索引等于尾元素索引的时候,或者说当首元素索引大于等于尾元素索引的时候,其实最多只能等于。这时就拆成一个个的元素了。
下面要并,怎么并?创建新数组来并,新数组多大?新数组的大小等于你要并的元素的个数,即你拆分后的尾元素索引减去首元素的索引再加1。并且在并的时候还要排序,怎么排?设置两个指针。如果前面的元素大于后面的,那么前面的元素进入新数组,并且前面的元素的指针加1,后面的大于前面的同理。直到两个指针都走到自身所在分部的末尾为止。这就是并。
这里面还用到了递归,这是很显而易见的。
下面来看一张图吧:
2.代码实现
下面看一下它的代码实现:
下面给出一点自己的思考:当某一次递归的第18行走完后,接下来走哪一行?走第17行,并且是上一次递归的第17行。
下面给出源码:
package Sorts;
import java.util.Arrays;
//归并排序
public class Merge {
public static void main(String[] args) {
int[] array = new int[]{13,56,2,8,19,34,29};
System.out.println("排序前:"+ Arrays.toString(array));
mergeSort(array,0,array.length-1);
System.out.println("排序后:"+Arrays.toString(array));
}
public static void mergeSort(int[] array, int low, int height){
if (low >= height)
return;
int mid = (low+height)>>>1;
mergeSort(array,low,mid);
mergeSort(array,mid+1,height);
merge(array,low,mid,height);
}
public static void merge(int[] array,int low,int mid,int height){
int[] ret = new int[height-low+1];
int i = 0;//新数组的索引
int s1 = low;//前一个分段的初始位置
int s2 = mid+1;//后一个分段的初始位置
while (s1<=mid && s2<=height){
if (array[s1]<=array[s2]){//比较元素的大小
ret[i++] = array[s1++];//赋值给新数组,然后索引++
}else {
ret[i] = array[s2];
i++;
s2++;
}
}
while (s1<=mid){//将前半段剩下的全部赋值到新数组中
ret[i++] = array[s1++];
}
while (s2<=height){//将后半段剩下的全部赋值到新数组中
ret[i++] = array[s2++];
}
for (int j = 0; j < ret.length; j++) {//将新数组中的元素全部挪到原数组中
array[j+low] = ret[j];
}
}
}
3.总结
其实重点还是这个双路递归,就是要弄清是怎么拆的,怎么并的。对于数组,我们一定一定一定要非常熟悉它的索引,并且要非常善于的使用它的索引。除此之外,数组还常常和指针(可以这样理解)联系在一起。