排序算法-归并排序

归并排序参考图

在这里插入图片描述

package com.test.sort;

import java.util.Arrays;

/**
 * 归并排序基本思想:
 *   归并排序分为两个阶段:
 *   第一阶段分:将待排序序列分为两个序列,再分别对两个序列再次分裂,直至分为一个最小单元,此时不可再分
 *   第二阶段治:将上面已经分割好的最小单元序列合并为一个有序序列,依次向上合并
 *   最终达到整个序列的排序目的
 */
public class MergeSortDemo {
    public static void main(String[] args) {
        int[] arr=new int[]{6,7,8,5,9,3,2,4};
        divide(0,arr.length-1,arr);
        System.out.println(Arrays.toString(arr));
    }

    /**
     *
     * @param left 待分割后的序列第一个元素下标
     * @param right 待分割后的序列最后一个元素下标
     * @param arr 原始数组
     */
    public static void divide(int left,int right,int[] arr){
        int middle=(left+right)/2;
        if(left<right){
            //左递归分割,分割完成的为{6,7}
           divide(left,middle,arr);
            //右递归分割,分割完成的为{2,4}
           divide(middle+1,right,arr);
           //对分割后的序列进行排序
           rule(left,right,arr);
        }
    }

    /**
     *  合并两个有序序列
     * @param left 分割后的序列第一个元素下标
     * @param right 分割后的序列最后一个元素下标
     * @param arr 原始数组
     */

    public static void rule(int left,int right,int[] arr){
        //左序列起始下标
        int i=left;
        //左序列最后一个元素下标
        int middle=(left+right)/2;
        //右序列起始下标
        int j=middle+1;
        //临时数组下标
        int temp=0;
        //临时数组
        int[] tempArr=new int[arr.length];
        while(j<=right && i<=middle){
            if(arr[i]>arr[j]){
               // leftArr={6,7} rightArr={5,8} 第一次合并后得到有序序列
                //如果左序列leftArr[0]>右序列rightArr[0](arr[middle+1]),把rightArr[0]放入临时数组,把rightArr的下一个元素再与leftArr[0]比较
                //如果左序列leftArr[0]<右序列rightArr[0](arr[middle+1]),把leftArr[0]放入临时数组,把leftArr的下一个元素再与rightArr[0]比较
                //例上面的序列,第一步 6>5,把5放入临时数组。第二步 6<8,把6放入临时数组,第三步 7<8,把7放入临时数组
              tempArr[temp]=arr[j];
                temp++;
                j++;
            }else{
                tempArr[temp]=arr[i];
                temp++;
                i++;
            }
        }
        //如果经过比较 右边序列全部放入临时数组,此时左边序列有剩余,把剩余的全部放入临时数组
       while (i<=middle){
           tempArr[temp++]=arr[i++];
       }
       while (j<=right){
           tempArr[temp++]=arr[j++];
       }

       //把临时数组有序的元素复制到原始数组中的对应位置
       // temp表示此时合并时有多少个元素
        for (int k=0;k<temp;k++){
            arr[left++]=tempArr[k];
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值