归并排序
思路
采用分治的思想,将数组二分成两段,然后再合并到一起,
2 7 5 3 0 4 5 9
2 7 5 3 0 4 5 9
2 7 5 3 0 4 5 9
2 7 5 3 0 4 5 9 分治到最小的子问题
2 7 3 5 0 4 5 9 开始合并
2 3 5 7 0 4 5 9 合并两个有序数组
0 2 3 4 5 5 7 9 排序完成
示例代码
import java.util.Arrays;
import java.util.Random;
public class MergeSort {
public void mergeSort(int[] nums){
if(nums.length<=1){
return;
}
int[] temp = new int[nums.length];
System.arraycopy(nums, 0, temp, 0, nums.length);
mergeSort(0 , nums.length-1 , temp , nums);
}
private void mergeSort(int left , int right, int[] temp , int[] nums) {
if(left>=right){
return;
}
int mid = left+(right-left)/2;
mergeSort(left , mid , temp , nums); // 分治
mergeSort(mid+1 , right ,temp , nums); // 分治
mergeArray(left , mid , right , temp , nums); // 合并两个有序数组
}
private void mergeArray(int left, int mid, int right, int[] temp , int[] nums) {
System.arraycopy(nums, 0, temp, 0, nums.length);
int i = left;
int j = mid+1;
for (int k = left; k <= right; k++) {
if(i==mid+1){
nums[k] = temp[j];
j++;
}else if(j==right+1){
nums[k] = temp[i];
i++;
}else if(temp[i]<=temp[j]){
nums[k] = temp[i];
i++;
}else {
nums[k] = temp[j];
j++;
}
}
}
public static void main(String[] args) {
int[] test = new Random().ints(0 , 1000).limit(10000).toArray();
int[] temp = Arrays.copyOf(test ,test.length);
new MergeSort().mergeSort(test);
Arrays.sort(temp);
for (int i = 0; i < temp.length; i++) {
if(test[i]!=temp[i]){
System.out.println("Err");
break;
}
}
System.out.println("Success");
}
}
算法分析
时间复杂度:O(nlog(n))
空间复杂度:O(n)
稳定性:稳定排序