归并排序
时间复杂度为O(nlog(n)),稳定排序,需要额外空间O(n),原地归并没看
归并排序的两种方式
自顶向下
先向下分治成规模为2的子问题,然后向上进行merge;
自底向上
在底部先进行规模为2的归并,然后处理规模为4,8...的问题向上归并
代码示例
merge方法用的同一个,额外空间用tmp;
package leet;
import org.junit.Test;
import java.util.Arrays;
/**
* @ClassName:MergeSort
* @Description:TODO
* @author:zgw
* @date:2022/9/28 21:09
*/
public class MergeSortTest {
int[] tmp;
@Test
public void test() {
int[] nums = new int[]{3, 2, 1, 0};
System.out.println(Arrays.toString(nums));
// 迭代方式归并 自底向上
iterationSort(nums);
System.out.println(Arrays.toString(nums));
}
@Test
public void test2() {
int[] nums = new int[]{3, 2, 1, 0};
System.out.println(Arrays.toString(nums));
// 递归归并 自顶向下
recursionSort(nums);
System.out.println(Arrays.toString(nums));
}
private void iterationSort(int[] nums) {
int n = nums.length;
tmp = new int[n];
for (int len = 1; len < n; len *= 2) {
for (int i = 0; i < n + 1 - len; i += 2 * len) {
merge(nums, i, i + len, Math.min(n, i + 2 * len - 1));
}
}
}
private void recursionSort(int[] nums) {
int n = nums.length;
tmp = new int[n];
doRecursionSort(nums, 0, n-1);
}
private void doRecursionSort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
doRecursionSort(nums, left, mid);
doRecursionSort(nums, mid + 1, right);
merge(nums, left, mid + 1, right);
}
private void merge(int[] nums, int leftStart, int rightStart, int rightEnd) {
int l = leftStart, r = rightStart;
int k = 0;
while(l < rightStart || r <= rightEnd) {
if (l >= rightStart) {
tmp[k++] = nums[r++];
} else if (r > rightEnd) {
tmp[k++] = nums[l++];
} else if (nums[l] <= nums[r]) {
tmp[k++] = nums[l++];
} else {
tmp[k++] = nums[r++];
}
}
for (int i = 0; i < k; i++) {
nums[leftStart + i] = tmp[i];
}
}
}
标签:tmp,归并,nums,int,void,len,排序
From: https://www.cnblogs.com/beichuang/p/16739665.html