Java数据结构 -- 归并排序

1.原理

归并排序采用的是分治算法, 将已有的子序列合并, 得到完全有序的序列; 即先使每个子序列有序, 再使子序列段间有序. 若将两个有序表合并成一个有序表, 称为二路归并.

执行流程:

1. 不断地将当前序列平均分割成2个子序列

直到不能再分割(即序列中只剩1个元素)

2. 不断地将2个子序列合并成一个有序序列

直到最终只剩下1个有序序列

2.代码实现

要将两个排好序的子序列合并成一个子序列的方法: 每次都是从未比较的两个子序列的最小值中选择一个更小值

 

public class mergeSort{
    public static void mergeSort(int[] array){
        mergeSortInternal(array, 0, array.length);
    }
    private static void mergeSortInternal(int[] array, int low, int high){ 
        if(low >= high-1){ //待排序区间是[low, high)
            return; //递归出口
        }
        //这块是递归分割的过程, 将其分割到不能分割的地步然后开始合并
        int mid = (low+high)/2;
        mergeSortInternal(array, low, mid);
        mergeSortInternal(array, mid, high);
        //开始合并过程
        merge(array, low, mid, high);
    }
    private static void merge(int[] array, int low, int mid, int high){ //合并过程
        int i = low;
        int j = mid;
        int length = high - low;
        int[] extra = new int[length]; //创建一个extra数组, 长度等于array数组长度
        int k = 0;
        //"下标为i<mid的区间和下标为j<high的区间"之间进行比较, 选择小的放入extra数组
        while(i<mid && j<high){  //i表示具体要比较的数所对应的下标, mid表示下标的边界
            //加入等于, 保证稳定性
            if(array[i] <= array[j]){ //数组中具体的数进行比较
                extra[k++] = array[i++]; //要将小的那个数放到extra数组中
            }else{
                extra[k++] = array[j++];
            }
        }
        //将while大循环比较完之后剩余区间内(只剩余i<mid区间或j<mid区间)的元素再进行比较, 选择小的元素放到extra数组
        while(i < mid){
            extra[k++] = array[i++];
        }
        while(j <high){
            extra[k++] = array[j++];
        }
        //从extra数组搬回array数组
        for(int t = 0; t < length; t++){  //注意这里是length,代表extra数组长度,不是array数组的长度array.length
            array[low + t] = extra[t]; //需要搬回原位置,从low开始
        }
    }
    public static void main(String[] args){ //打印测试
        int[] array = {5,6,13,51,8,7,4,21};
        mergeSortInternal(array, 0, array.length);
        for(int i = 0; i <= array.length - 1; i++){
            System.out.print(array[i] + " ");
        }
    }
}

3.性能

时间复杂度 O(nlog(n)) 数据不敏感

空间复杂度 O(n) 数据不敏感

稳定

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值