归并排序基本思想
简介: 归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法采用分治法(Divide and Conquer)的思想。分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"归并"在一起,即分而治之。
描述:
首先,是打乱的一个数组,将他们不断的二分,直到最小单元,然后从最小单元再不断的两两比较,合并成一个新的数组,这样不断的比较合并,就可以达到排序的目的了。
这里不断的二分,是采用的递归的方法,直到达到最小单元得到一个返回值,到此是分治思想中的分。然后再从最小单元不断的获得返回值数组,直到成为最后一个。该部分是分治思想的治。
代码实现:
package merge;
public class Merge {
public static void main(String[] args) {
int arr[] = { 1, 3, 5, 6, 2, 4, 7 };
int[] newArr = mergeSort(arr,0,arr.length-1);
for(int i = 0;i<newArr.length;i++) {
System.out.println(newArr[i]);
}
}
public static int[] mergeSort(int arr[],int l,int h) {
//判断是否最最小单元,当最小单元为1时,就会返回。
if (l==h) {
return new int[] {arr[l]};
}
//求数组的中间值,不用(l+h)/2是为了防止超过Integer类型的最大值
int mid = l+(h-l)/2;
//拆分的两个数组,递归调用
int[] leftArr = mergeSort(arr, l, mid);
int[] rightArr = mergeSort(arr, mid+1, h);
//开辟一个新的空间,用来存放归并的数据
int newArr[] = new int[leftArr.length+rightArr.length];
//依次比较归并的两个数组中的数据,哪一个数据小,就放到新的数组,并且指针后移
int i = 0,j = 0,k = 0;
while (i < leftArr.length && j < rightArr.length) {
newArr[k++] = leftArr[i] <= rightArr[j] ? leftArr[i++] : rightArr[j++];
}
//存在一个数组已经全部放到了新的数组,另一个数组还有剩余的数据的情况,所以就判断,
//哪个数组里还有数据,就将它们依次全部放入新的数组。
while (i < leftArr.length) newArr[k++] = leftArr[i++];
while (j < rightArr.length) newArr[k++] = rightArr[j++];
return newArr;
}
}
复杂度分析:
- 时间复杂度:O(
n
l
o
g
2
n
nlog_2^n
nlog2n )
这个 l o g 2 n log_2^n log2n是怎么来的呢?
这个指的是二分的次数,比如8,它需要 l o g 2 8 = 3 log_2^8=3 log28=3次,才能二分到最小单元,最小单元执行的次数都是n,所以时间复杂度为 n l o g 2 n nlog_2^n nlog2n - 空间复杂度:O(n),虽然在递归过程中会开辟很多小的空间,但是最大使用的内存空间是n。