归并排序

归并排序

时间复杂度为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];
        }
    }
}

posted @ 2022-09-28 21:33  北de窗  阅读(26)  评论(0)    收藏  举报