栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

在一个排好序的数组(对数组进行排序)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在一个排好序的数组(对数组进行排序)

排序 归并排序 思想

归并排序算法有两个基本的操作,

一个是分,也就是把原数组划分成两个子数组的过程。

一个是治,它将两个有序数组合并成一个更大的有序数组。

它将数组平均分成两部分: center = (left + right)/2,当数组分得足够小时—数组中只有一个元素时,只有一个元素的数组自然而然地就可以视为是有序的,此时就可以进行合并操作了。

因此,上面讲的合并两个有序的子数组,是从 只有一个元素 的两个子数组开始合并的。

当合并两个数组的时候,如果遇到待比较的元素是相同的值时,那么先拷贝右边的,后拷贝左边的。其实先后无所谓,主要是为了方便统一,在类似的题目:找数组小和的题目。考虑右边有多少比自己大的,那么需要先把右边的拷贝进去,因为拷贝左边进数组也不能确定右边数组有多少比自己大的元素。

所以在比较的时候,只有左边严格的小于右边,才会进行拷贝。

代码实现
package com.vitamin.sort;

import org.junit.Test;

import java.util.Arrays;


public class MergeSort {


    @Test
    public void test() {
        MergeSort mergeSort = new MergeSort();
        mergeSort.sort();
        mergeSort.print();
    }


    int arr[] = new int[]{5, 6, 7, 10, 2, 30, 8, 9, 10, 2};

    public void print() {
        Arrays.stream(arr).forEach(System.out::println);
    }

    public void sort() {
        if (arr == null || arr.length <= 1) {
            return;
        }
        sortArr(0, arr.length - 1);
    }

    private void sortArr(int begin, int end) {
        if (end == begin) {
            return;
        }
        // 分治,分别排序
        int middle = begin + ((end - begin) >> 1);
        sortArr(begin, middle);
        sortArr(middle + 1, end);
        // 进行归并操作
        merge(begin, middle, end);

    }

    
    private void merge(int begin, int middle, int end) {

        if (end == begin) {
            return;
        }
        //创建辅助数组
        int helpArr[] = new int[end - begin + 1];
        int i = 0;
        int leftStart = begin;
        int rightStart = middle + 1;
        while (leftStart <= middle && rightStart <= end) {
            helpArr[i++] = arr[leftStart] < arr[rightStart] ? arr[leftStart++] : arr[rightStart++];
        }
        while (leftStart <= middle) {
            helpArr[i++] = arr[leftStart++];
        }
        while (rightStart <= end) {
            helpArr[i++] = arr[rightStart++];
        }
        // 原数组实现排序
        for (int j = 0; j < helpArr.length; j++) {
            arr[j + begin] = helpArr[j];
        }

    }

}

数组小和

注意:小和的求解一定要在数组排序之前进行。

private int sortArr(int begin, int end) {
    if (end == begin) {
        return 0;
    }
    // 分治,分别排序
    int middle = begin + ((end - begin) >> 1);
    return sortArr(begin, middle) +
            sortArr(middle + 1, end) +
            // 进行归并操作
            merge(begin, middle, end);

}


private int merge(int begin, int middle, int end) {

    // 只有一个元素的时候是不会产生小和的
    if (end == begin) {
        return 0;
    }
    //创建辅助数组
    int helpArr[] = new int[end - begin + 1];
    int i = 0;
    int leftStart = begin;
    int rightStart = middle + 1;
    // 小和
    int sum = 0;
    // 1 1 1 2 5    1 1 5 5 6
    // 1 1
    while (leftStart <= middle && rightStart <= end) {
        sum += arr[leftStart] < arr[rightStart] ? arr[leftStart] * (end - rightStart + 1) : 0;
        helpArr[i++] = arr[leftStart] < arr[rightStart] ? arr[leftStart++] : arr[rightStart++];

    }
    while (leftStart <= middle) {
        helpArr[i++] = arr[leftStart++];
    }
    while (rightStart <= end) {
        helpArr[i++] = arr[rightStart++];
    }
    // 原数组实现排序
    for (int j = 0; j < helpArr.length; j++) {
        arr[j + begin] = helpArr[j];
    }
    return sum;

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/776236.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号