java两种实用的排序(插入排序、归并排序)

插入排序

插入排序是多种较为实用的排序方法之一。很多更高效的排序,当输入规模降低到一定程度就会切换到插入排序,因为在局部有序并且规模较小的情况下,插入排序非常高效。以下为代码实现。

/**
 * Created by tiantian on 2018/7/9.
 */
public class InsertSort {
    
    public static void sort(Integer[] destArray) {
        int len = destArray.length;

        for (int i = 1; i < len; i++) {
            Integer j = i;
            Integer temp = destArray[j];
            while (j > 0 && destArray[j-1] > temp) {
                destArray[j] = destArray[j-1];
                j--;
            }
            destArray[j] = temp;
        }
    }

    public static void main(String[] args) {
        Random random =  new Random();
        Integer[] array = new Integer[20];
        for (int i = 0; i < 20; i++) {
            Integer number = random.nextInt(100);
            array[i] = number;
            System.out.print(number + ",");
        }
        
        InsertSort.sort(array);
        System.out.println("");
        for(Integer i : array) {
            System.out.print(i + ",");
        }
    }
}

测试实用Random随机生成20个100以内的数:

67,64,95,52,62,75,3,44,14,86,75,10,43,25,17,24,11,53,69,63
运行后输出如下:

3,10,11,14,17,24,25,43,44,52,53,62,63,64,67,69,75,75,86,95

归并排序

归并排序是较高级的排序方式,最坏情况时间复杂度为logN。该排序方式的分治思想非常值得学习。分治思想大概是这样,将规模较大的问题拆分为性质相同的小规模问题,小规模问题在次以相同方式拆分,直到出现基本情况(不能再拆分时)时返回。分治方法解决问题时将问题抽象为三步:分解、解决、合并。分解就是将问题拆分成更小规模;解决就是解决小规模问题;合并是将小规模问题解决后的结果合并。以下为java的实现。

/**
 * Created by tiantian on 2018/7/10.
 */
public class MergeSort {
    
    public static void sort(Integer[] array, int low, int height) {
        if (low == height) {
            return;
        }
        // 分解 
        int middle = (low+height) / 2;
        
        // 解决
        sort(array, low, middle);
        sort(array, middle+1, height);
        
        // 合并
         merge(array, low, middle, height);
    }
    
    public static void merge(Integer[] array, int low, int middle, int height) {
        // 将已有序的两个子数组,存入两个临时数组中
        int len1 = middle - low + 1;
        int len2 = height - middle;
        Integer[] temp1 = new Integer[len1+1];
        Integer[] temp2 = new Integer[len2+1];

        for (int i = 0; i < len1; i++) {
            temp1[i] = array[low+i];
        }
        
        middle++;
        for (int j = 0; j < len2; j++) {
            temp2[j] = array[middle+j];
        }
        
        // 为了保证归并操作完整执行,加入两个哨兵
        temp1[len1] = 1000;
        temp2[len2] =1000;
        
        int m = 0,n = 0;
        // 归并操作
        for (int i = low; i <= height; i++) {
            if (temp1[n] < temp2[m]) {
                array[i] = temp1[n++];
                continue;
            } else {
                array[i] = temp2[m++];
            }
        }
    }

    public static void main(String[] args) {
        Random random =  new Random();
        Integer[] array = new Integer[20];
        
        for (int i = 0; i < 20; i++) {
            Integer number = random.nextInt(100);
            array[i] = number;
            System.out.print(number + ",");
        }

        MergeSort.sort(array, 0, array.length-1);
        System.out.println("");
        System.out.println("");
        for(Integer i : array) {
            System.out.print(i + ",");
        }
        
    }
}

测试方法同插入排序。

输入:62,29,93,74,69,73,83,21,33,33,11,34,80,82,13,17,92,13,63,2

输出:2,11,13,13,17,21,29,33,33,34,62,63,69,73,74,80,82,83,92,93

算法思想不难,代码也没多少行,但调试到正确运行确实挺不容易(递归调用一层套一层,调着调着就晕了...)。因此写入博客记录一下,同时也希望大家能参考交流,共同进步。

更多原创内容:

原型模式

单例模式

建造者模式

工厂模式

策略模式



猜你喜欢

转载自blog.csdn.net/m0_37577221/article/details/81058459
今日推荐