数据结构与算法(四)

175 阅读1分钟
  • 归并排序
    • 思路:使用递归先逐层分为左右两部分,并各自排好序再合并
public static void mergeSort1(int[] arr, int left, int right) {
        if (left == right) {
            return;
        }
        int center = (right - left) / 2 + left;
        mergeSort1(arr, left, center);
        mergeSort1(arr, center + 1, right);
        merge(arr, left, center, right);
    }

    private static void merge(int[] arr, int left, int center, int right) {
        int index_left = left - 1;
        int index_right = center;
        int[] new_arr = new int[right - left + 1];
        int index = 0;
        while (index_left < center && index_right < right) {
            if (arr[index_left] <= arr[index_right]) {
                new_arr[index++] = arr[index_left++];
            } else {
                new_arr[index++] = arr[index_right++];
            }
        }

        for (; index_left < center; index_left++) {
            new_arr[index++] = arr[index_left];
        }

        for (; index_right < right; index_right++) {
            new_arr[index++] = arr[index_right];
        }

        for (int i = left - 1; i < right; i++) {
            arr[i] = new_arr[i - left + 1];
        }
    }

  • 衍生题目: 在一个数组中,一个数左边比它小的数的总和,叫数的小和,所有数的小和累加起来,叫数组小和。求数组小和
public static int mergeSort1(int[] arr, int left, int right) {
        if (left == right) {
            return 0 ;
        }
        int merge = 0;
        int center = (right - left) / 2 + left;
        int m_l = mergeSort1(arr, left, center);
        int m_r = mergeSort1(arr, center + 1, right);
        merge = merge(arr, left, center, right);
        return merge+m_l+m_r;

    }

    private static int merge(int[] arr, int left, int center, int right) {
        int index_left = left - 1;
        int index_right = center;
        int[] new_arr = new int[right - left + 1];
        int index = 0;
        int smallSort = 0;
        while (index_left < center && index_right < right) {
            if (arr[index_left] < arr[index_right]) {
                //计算小和
                smallSort += arr[index_left] * (right-index_right);
                new_arr[index++] = arr[index_left++];
            } else {
                new_arr[index++] = arr[index_right++];
            }
        }

        for (; index_left < center; index_left++) {
            new_arr[index++] = arr[index_left];
        }

        for (; index_right < right; index_right++) {
            new_arr[index++] = arr[index_right];
        }

        for (int i = left - 1; i < right; i++) {
            arr[i] = new_arr[i - left + 1];
        }
        return smallSort;
    }