这篇文章我们来讲一下十大排序中的归并排序。
目录
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.总结
其实重点还是这个双路递归,就是要弄清是怎么拆的,怎么并的。对于数组,我们一定一定一定要非常熟悉它的索引,并且要非常善于的使用它的索引。除此之外,数组还常常和指针(可以这样理解)联系在一起。