题目描述:
把一个乱序的数组排序后变为一个有序数组。
图示:
思考:
利用递归采用分治的策略,大致意思就是两个儿子都搞(有序)好了,那么合起来的父亲肯定就搞好了,递归一般不好判断,但是一般是查看递归的末尾情况,所以归并的分治情况就是,当儿子被分为两个,且各自只有一个元素的时候,那么这两个儿子不用排序也是有序的,然后把连个儿子排序后,往上推就能够排好序了。归并排序的空间复杂程度为O(N),时间复杂程度为
时间复杂度
为O(nlogn),并且他是稳定的,因为遇到相等元素从两个儿子的元素到暂存(temp)顺序不变
代码(java):
package 归并排序;
import java.util.Arrays;
public class mergeSortTest {
public static void main(String[] args) {
int[] nums = { 2, 7, 8, 3, 1, 6, 9, 0, 5, 4 };
mergeSortTest.sort(nums, 0, nums.length-1);
System.out.println(Arrays.toString(nums));
}
static int[] sort(int[] nums,int left,int right){
//if(nums == null){
//return null;
//}
//找到分治中点
int mid = (left + right) / 2;
//如果left和right没有碰头说明,没有找到只有一个元素的子序列,因为只有一个元素的数组自然有序
if(left < right){
sort(nums,left,mid);
sort(nums,mid + 1,right);
merge(nums,left,mid,right);
}
return nums;
}
static void merge(int[] nums ,int left, int mid, int right){
int[] temp = new int[right - left + 1];
int leftStart = left;
int rightStart = mid + 1;
int tempStart = 0;
while(leftStart <= mid && rightStart <= right){
if(nums[leftStart] < nums[rightStart]){
temp[tempStart] = nums[leftStart];
leftStart++;
}
else{
temp[tempStart] = nums[rightStart];
rightStart++;
}
tempStart++;
}
while(leftStart <= mid){
temp[tempStart] = nums[leftStart];
leftStart++;
tempStart++;
}
while(rightStart <= right){
temp[tempStart] = nums[rightStart];
rightStart++;
tempStart++;
}
for(int i = 0 ; i < temp.length ; i++){
nums[left + i] = temp[i];
}
}
}