希尔排序和归并排序

2019-04-06  本文已影响0人  angeliur
public class ShellSort {

    public static void main(String[] args){
        int[] arr = {9,6,11,3,5,12,8,7,10,15,14,4,1,13,2};
        sort(arr);
        print(arr);
    }

    private static void print(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            System.out.print( arr[i] + " ");
        }
    }

    private static void sort(int[] arr) {
        int h = 1;
        while (h <= arr.length/3){
            h = h * 3 + 1;
        }
        for (int gap = h; gap > 0 ; gap = (gap - 1)/3) {
            for (int i = gap;i < arr.length;i++){
                for (int j = i;j > gap - 1;j-=gap){
                    if (arr[j] < arr[j - gap]){
                        swap(arr,j,j - gap);
                    }
                }
            }
        }

    }

    private static void swap(int[] arr,int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
public class MergeSort {

    public static void main(String[] args){
        //arr数组已经分为{1,4,7,8}和{3,6,9}两个排好序的数组,进行归并
        int[] arr = {1,4,7,8,3,6,9};
        merge(arr);
        print(arr);


        //数组并不是左边两边已经排好序的就递归调用sort方法,直到左右两边都是有序数组,最后进行merge调用
        int[] arr2 = {2,4,1,6,9,3,8,2,7};
        sort(arr2,0.arr2.length - 1);
        print(arr);
    }

    private static void sort(int[] arr,int left,int right){
        if (left == right) return;
        //将数组分成两半
        int mid = left + (right - left)/2;

        //左边排序
        sort(arr,left,mid);
        //右边排序
        sort(arr,mid + 1,right);

        //merge归并
        merge(arr,left,mid + 1,right);

    }

    private static void merge(int[] arr) {
        //mid取数组中间的数,将数组分为前后两部分
        int mid = arr.length / 2;
        int[] temp = new int[arr.length];

        int i = 0;
        int j = mid + 1;
        int k = 0;

        while (i <= mid && j < arr.length){
            if (arr[i] <= arr[j]){
                temp[k] = arr[i];
                i++;
            }else {
                temp[k] = arr[j];
                j++;
            }
            k++;
        }

        //归并之后如果前半部分的数有剩下的则把剩下的所有数依次添加到数组中
        while (i <= mid){
            temp[k++] = arr[i++];
        }

        //归并之后如果后半部分的数有剩下的则把剩下的所有数依次添加到数组中
        while (j < arr.length){
            temp[k++] = arr[j++];
        }

    }

    //优化的merge方法,可以指定数组的一部分来排序
    // leftPoint:左半部分从哪开始的指针
    // rightPoint:右半部分从哪开始的指针
    // rightBound:右边边界的索引
    private static void merge(int[] arr,int leftPoint,int rightPoint,int rightBound) {
        //mid取数组中间的数,将数组分为前后两部分
        int mid = rightPoint - 1;
        int[] temp = new int[rightBound - leftPoint + 1];

        int i = leftPoint;
        int j = rightPoint;
        int k = 0;

        while (i <= mid && j <= rightBound){
            if (arr[i] <= arr[j]){
                temp[k] = arr[i];
                i++;
            }else {
                temp[k] = arr[j];
                j++;
            }
            k++;
        }

        //归并之后如果前半部分的数有剩下的则把剩下的所有数依次添加到数组中
        while (i <= mid){
            temp[k++] = arr[i++];
        }

        //归并之后如果后半部分的数有剩下的则把剩下的所有数依次添加到数组中
        while (j <= rightBound){
            temp[k++] = arr[j++];
        }

        for (int m = 0; m < temp.length; m++) {
            arr[leftPoint + m] = temp[m];
        }

    }

    private static void print(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            System.out.print( arr[i] + " ");
        }
    }

}
上一篇 下一篇

猜你喜欢

热点阅读