数据结构与算法(十)

归并排序

对数列进行分组比较,最后递归合并在一起,赋值给原数组

用到最小位置,最大位置,中间位置来划分,很有创造性的一个排序方法。

指针索引之类的要加深理解,考虑移动方向临界状态满足特殊情况,一定可以满足一般情况。

package com.bjsxt.Sort;

import java.util.Arrays;

//归并排序
public class MergeSort {
    public static void main(String[] args){
        int[] arr = new int[]{1,3,5,2,4,6,8,10,0};
        System.out.println(Arrays.toString(arr));
        mergeSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    //归并排序
    public static void mergeSort(int[] arr,int low,int high){
        int middle=(high+low)/2;
        if(low<high){
            //处理左边
            mergeSort(arr,low,middle);
            //处理右边
            mergeSort(arr,middle+1,high);
            //归并
            merge(arr,low,middle,high);


        }
    }

    public static void merge(int[] arr,int low,int middle, int high){
        //用于储存归并后的临时数组
        int[] temp = new int[high-low+1];
        //记录第一个数组中需要遍历的下标
        int i = low;
        //记录第二个数组中需要遍历的下标
        int j = middle +1;
        //用于记录临时数组中存放的下标
        int index = 0;
        //遍历两个数组取出小的数字,放入临时数组中
        while(i<=middle&&j<=high){
            //第一个数组的数据更小
            if(arr[i]<=arr[j]){
                //把小的数据放入临时数组中
                temp[index]=arr[i];
                //让下标向后移一位
                i++;
            }else{
                temp[index]=arr[j];
                j++;
            }
            index++;
        }
        //处理多余的数据
        while(j<=high){
            temp[index]=arr[j];
            j++;
            index++;
        }
        while(i<=middle){
            temp[index]=arr[i];
            i++;
            index++;
        }
        //把临时数组中的数据重新存入原数据
        for(int k=0;k<temp.length;k++){
            arr[k+low]=temp[k];
        }
    }
}

执行结果

[1, 3, 5, 2, 4, 6, 8, 10, 0]
[0, 1, 2, 3, 4, 5, 6, 8, 10]

百度后的java实现归并排序

package com.bjsxt.Sort;


import java.util.Arrays;

public class test {
    // private static long sum = 0;

    /**
     *  * <pre>
     *  * 二路归并
     *  * 原理:将两个有序表合并和一个有序表
     *  * </pre>
     *  *
     *  * @param a
     *  * @param s
     *  * 第一个有序表的起始下标
     *  * @param m
     *  * 第二个有序表的起始下标
     *  * @param t
     *  * 第二个有序表的结束下标
     *  *
     */
    private static void merge(int[] a, int s, int m, int t) {
        int[] tmp = new int[t - s + 1];
        int i = s, j = m, k = 0;
        while (i < m && j <= t) {
            if (a[i] <= a[j]) {
                tmp[k] = a[i];
                k++;
                i++;
            } else {
                tmp[k] = a[j];
                j++;
                k++;
            }
        }
        while (i < m) {
            tmp[k] = a[i];
            i++;
            k++;
        }
        while (j <= t) {
            tmp[k] = a[j];
            j++;
            k++;
        }
        System.arraycopy(tmp, 0, a, s, tmp.length);
    }

    /**
     *  *
     *  * @param a
     *  * @param s
     *  * @param len
     *  * 每次归并的有序集合的长度
     */
    public static void mergeSort(int[] a, int s, int len) {
        int size = a.length;
        int mid = size / (len << 1);
        int c = size & ((len << 1) - 1);
        // -------归并到只剩一个有序集合的时候结束算法-------//
        if (mid == 0)
            return;
        // ------进行一趟归并排序-------//
        for (int i = 0; i < mid; ++i) {
            s = i * 2 * len;
            merge(a, s, s + len, (len << 1) + s - 1);
        }
        // -------将剩下的数和倒数一个有序集合归并-------//
        if (c != 0)
            merge(a, size - c - 2 * len, size - c, size - 1);
        // -------递归执行下一趟归并排序------//
        mergeSort(a, 0, 2 * len);
    }

    public static void main(String[] args) {
        int[] a = new int[]{4, 3, 6, 1, 2, 5};
        System.out.println(Arrays.toString(a));
        mergeSort(a, 0, 1);
        for (int i = 0; i < a.length; ++i) {
            System.out.print(a[i] + " ");
        }
    }
}

执行结果

[4, 3, 6, 1, 2, 5]
1 2 3 4 5 6 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值