归并排序:
时间复杂度:时间复杂度主要取决于合并的时间。是n*log(n)
空间复杂度:在合并的时候,使用了额外的数组存储排序结果,所以空间复杂度不是O(1)
原地排序算法:不是原地排序算法。
稳定排序算法:在排序的时候,前后大小相等的元素,先排前边数组的元素,就可以保证排序的稳定性。
时间复杂度推导方法:
T(n) = 2*T(n/2) + n = 4*T(n/4) + 2n =8*T(n/8) + 3n .......... = n*T(1) + m * n
2 ^ m = n
m = log(n)
T(n) = n*T(1) + n * log(n) = n * log(n)
package cm.com.algorithm.sort;
/**
* 归并排序:
* 归并排序主要用的是一个分治的思想。
* 将数组分为前后两个部分,分别对前后两个部分进行排序。排序之后,再将排序后的数组有合并。
* 分的时候一直分到数组长度为1为止。
* 采用的递归的方式实现。
*
* @author liushuai13@meicai.cn
* @date 2019-06-06 20:34
*/
public class MergeSort {
private static int[] intArray = {9,7,5,3,6,5,8,9,5,4};
public static void main(String[] args) {
sort();
printArray();
}
/**
* 对数组排序
*/
private static void sort(){
intArray = split(intArray,0,intArray.length - 1);
}
private static int[] split(int[] intArray, int begin, int end) {
int [] left = null;
int [] right = null;
if (end - begin > 1){
left = split(intArray,begin,(begin + end)/2);
right = split(intArray,(begin + end)/2 + 1,end);
}else if (end - begin == 1){
left = new int[]{intArray[begin]};
right = new int[]{intArray[end]};
}else if (end - begin == 0){
return new int[]{intArray[begin]};
}else {
System.out.println("error..........");
}
return merge(left,right);
}
private static int[] merge(int[] left, int[] right) {
int [] result = new int [left.length + right.length];
int m = 0;
for (int i = 0,j = 0; i < left.length || j < right.length; ) {
if (i == left.length){
result[m] = right[j];
m++;
j++;
}else if (j == right.length){
result[m] = left[i];
m++;
i++;
}else {
if (left[i] <= right[j]){
result[m] = left[i];
i++;
}else {
result[m] = right[j];
j++;
}
m++;
}
}
return result;
}
/**
* 打印数组
*/
private static void printArray(){
for (int i = 0; i < intArray.length; i++) {
if ( i < intArray.length - 1 ){
System.out.print(intArray[i]+",");
continue;
}
System.out.println(intArray[i]);
}
}
}
归并排序原理示意图:
图片来源于-极客时间-数据结构与算法之美