首页 > 其他分享 >归并排序

归并排序

时间:2022-11-01 19:23:48浏览次数:41  
标签:归并 right int mid step array 排序 left

public class MergeSort {

    /**
     * ans2: 非递归实现
     */
    public static void mergeSort2(int[] array) {
        if(array == null || array.length < 2) {
            return;
        }
        int step = 1; //初始步长
        int len = array.length;
        while (step < len) {
            int left = 0;
            while (left < len) {
                int mid = 0;
                //左边数组坐标 left...mid
                if(len - left > step) { //数组内元素够step个
                    mid = left + step - 1;
                } else {
                    break;  //左边数组都凑不够
                }
                int right = 0;
                //右边数组范围 mid+1 ....right
                if(len - mid > step) {
                    right = mid + step;
                } else {
                    right = len - 1;
                }
                mergeSortedSubArray(array,left,mid,right);  //合并数组
                if(right == len - 1) {
                    break;
                } else {
                    left = right + 1;
                }
            }
            if(step > (len >> 1)) {  //为了安全,防止step翻倍之后溢出
                break;
            } else {
                step <<= 1;
            }
        }
    }
    /**
     * ans1:归并排序递归实现
     */
    public static void mergeSort1(int[] array) {
        if(array == null || array.length < 2) {
          return;
        }
        process(array,0,array.length-1);
    }
    //递归调用实现
    private static void process(int[] array, int left,int right) {
        if(left == right) {  //定义递归结束条件
            return;
        }
        //先从中间咔嚓一刀,左右两边分别排序,再合并
        int mid = left + ((right - left) >> 1);    //防止数组过大时,left+right溢出
        process(array,left,mid);  //先排左边
        process(array,mid+1,right);           //再排右边
        mergeSortedSubArray(array,left,mid,right);
    }
    //合并两段排序好的数组
    private static void mergeSortedSubArray(int[] array, int left, int mid, int right) {
        int[] assist = new int[right-left+1];
        int p = left;
        int q = mid+1;
        int i = 0;  //assist的索引
        while (p <= mid && q <= right) {
            assist[i++] = array[p] < array[q] ? array[p++] : array[q++];
        }
        //当上边这个循环结束后,说明p和q至少有一个越界了,也就是说至少有一个数组合并完了
        //接下来就是合并未处理完的数组中的值,下边两个只会进一个
        while (p <= mid) {
            assist[i++] = array[p++];
        }
        while (q <= right) {
            assist[i++] = array[q++];
        }
        //然后把合并后的数组  更新到员数组中
        for (int j = 0; j < assist.length; j++) {
            array[left+j] = assist[j];
        }
    }

    public static void main(String[] args) {
        //测试递归
        //ArrayUtil.testArraySorted(100000,50,100,MergeSort.class,"mergeSort1");

        int[] ints = ArrayUtil.generateRandomArray(20, 20);
        ArrayUtil.printArray(ints);
        mergeSort2(ints);
        ArrayUtil.printArray(ints);
        mergeSort1(ints);
        ArrayUtil.printArray(ints);
    }
}

标签:归并,right,int,mid,step,array,排序,left
From: https://www.cnblogs.com/xinay/p/16848866.html

相关文章

  • 插入排序
    插入排序是基础简单,同时效率也不高的排序voidinsertion_sort(vector<int>&nums){ intn=nums.size(); //把第一个当作是有序序列,从第二个开始操作 for(inti=......
  • 用C语言实现的对单链表进行快速排序的算法
    typedefstructLinkNode{intdata;structLinkNode*next;}LinkNode,*LinkList;voidquickSortLinkList(LinkListlist,LinkNode*end){LinkNode......
  • Redis 中两个字段排序
    参考:Redis中两个字段排序 redis如何实现多字段排序1.多个维度使用数据库查询排序输出,目前使用的方式。 Redis用一个SortedSet解决按两个字段排序的问题,也就是......
  • 剑指offer——数字在排序数组中出现的次数
    题目描述:统计给定数字k在排序数组中出现的次数思路1:最容易想到但是效率不高的一个方法就是遍历整个数组,统计k出现的次数(for循环就能解决,不赘述)思路2:由于题目给出是排序......
  • 快速排序算法
    packagesorting;publicclassQuick{/*双指针,设置两个参数,left和right,分别从左到右边寻找第一个大于a[0](数组的第一个元素)的值,从右到左寻找第一个小于i的值,并进行交换位置......
  • vue之列表排序-计算属性的应用
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><metahttp-e......
  • 面试之基础算法题:求一个数字在给定的已排序数组中出现的起始、终止索引号(Java版)
    题目给定一个升序的整数数组,查找某一个值在数组中出现的索引号,例如,输入数组​​[2,3,3,4,4,5]​​​;查找的数是3,则返回​​[1,2]​​。时间复杂度要求为O(logN)。思路......
  • 数据结构中的七大排序算法—1
        今天我们来讲解有关数据结构的知识,首先我们讲解数据结构的语言是C语言,使用的是vs2013编译器进行测试代码。    在我们的生活中,很多东西都是有排序的,就比......
  • 堆排序的基本知识
    堆的性质分为大根堆和小根堆,性质为结点的左右孩子大于或小于根节点(1)堆是一颗完全二叉树;(2)小(大)顶堆中的每一个节点都不小于(不大于)它的父节点;(3)堆的插入、删除......
  • 1045 快速排序
    题目: 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。给定划分......