Javaは、バブリング、高速、選択、挿入、ヒルソートコード、および簡単な命令を実装しています

public class Main {

    static int input[] = {3, 8, 1, 6, 7, 2, 4, 9, 5};

    public static void main(String[] args) {
        System.out.println("SimpleCodeSimpleLife!");
//        maopao(input);
//        kuaisu(input, 0, input.length - 1);
//        xuanze(input);
//        charu(input);
        shell(input);

        //打印结果
        printToCMD(input);
    }

    //输出
    public static void printToCMD(int[] arr) {
        for (int i = 0, len = arr.length; i < len; i++) {
            System.out.print(arr[i]);
        }
    }

    /*
     * 方法:冒泡排序
     * 时间复杂度:O(n²)
     * 思路:很直白的算法,从数组的第一个数字开始和数组的下数字一个作比较,
     * 把大的放在后面,小的放前面,就像挤泡泡一样一步一步把大的挤到数组的最后,
     * 这样一轮下来,虽然数组没有完全有序,但是最大的一定被挤到了数组的最后一位,
     * 这样再从头挤一次,会把第二大的数字挤到倒数第二位置,
     * 以此类推,循环操作所有的元素后,每个数字都找到了自己作为最大值身份应该处于的位置。
     *
     * */
    //冒泡排序
    public static void maopao(int[] arr) {

        //从第一个元素开始把最大的一步步往上冒泡(挤)
        for (int i = 0; i < arr.length - 1; i++) {
            //已经冒泡到最后的一定是最大的,所以下一次只需要冒泡到arr.length - 1 - i,可以省点时间。当然冒泡到arr.length - 1也不算错。
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    /*
     * 方法:快速排序
     * 时间复杂度:O(nlogn)
     * 思路:可以不必在意`快速`这个名字,虽然它的效率比冒泡高,是冒泡的加强版。
     * 我们看看它的具体思路:把一个数组的 `第一个值` 作为依据值,然后把所有的值和这个值比较,把小于它的放在左边,比他大的放在右边。
     * 这样,结果就类似这样:2543 6 879(为了方便看,我加了空格), 左边的虽然是无序的但都比6小,右边同理都比6大,
     * 下面再将左侧(2543)和右侧(879)当作新的数组分别重复执行上面的操作,这样就拆成4个数组,
     * 虽然小数组内部是无序的,但数组块和数组块是有序的。以此类推,最后每个小数组有序后,大的数组也就是有序的了。
     * 可以大体猜到需要使用递归实现数组的左右分类,每个分类的小数组在递归调用左右分类。
     *
     * */
    public static void kuaisu(int[] arr, int startCursor, int endCursor) {
        int middle = getMiddle(arr, startCursor, endCursor);
        //如果middle就是起始的位置,说明已经是有序的不需要拆成左右,可以结合getMiddle方法理解。
        if (middle > startCursor) {
            kuaisu(arr, startCursor, middle);
            kuaisu(arr, middle + 1, endCursor);
        }
    }

    //快排取中点
    public static int getMiddle(int[] arr, int startCursor, int endCursor) {
        int bak = arr[startCursor];//用于判断放左放右的标准
        while (startCursor < endCursor) {
            while (startCursor < endCursor && arr[endCursor] > bak) {
                endCursor--;
            }
            arr[startCursor] = arr[endCursor];
            while (startCursor < endCursor && arr[startCursor] < bak) {
                startCursor++;
            }
            arr[endCursor] = arr[startCursor];
        }
        arr[startCursor] = bak;
        return startCursor;//此时startCursor和endCursor相等,返回哪个都一样
    }

    /*
     * 方法:选择排序
     * 时间复杂度:O(n²),虽然和冒泡一样都是n²,但实际上比冒泡高效点,因为它在最坏情况下元素作交换的次数比冒泡少,而且思路也更简单。
     * 思路:给定一个数组,从头开始比较,把数组里最小的取出来和第一个交换,然后继续从第二个开始找出剩下里面最小的和第二个交换,
     * 以此类推,不断找出最小的排列起来,最后就是有序的了。
     * */
    public static void xuanze(int[] arr) {
        for (int i = 0, len = arr.length; i < len; i++) {
            for (int j = i; j < len; j++) {
                int i_min = i;//记录最小的位置,初始化是自己
                if (arr[j] < arr[i_min]) {
                    i_min = j;
                }
                if (i != i_min) {
                    int temp = arr[i];
                    arr[i] = arr[i_min];
                    arr[i_min] = temp;
                }
            }
        }
    }

    /*
     * 方法:插入排序
     * 时间复杂度O(n²)
     * 说明:插入排序和选择排序很像,插入排序是从右边剩余的子项里找出最小的放在左边(遍历右侧),
     * 而插入排序则是取右侧一个值在左侧找到合适的位置(左侧左侧)。
     * 具体思路是,从第二个数字(索引1)开始,取出来向前逐个比较,因为左侧是排序后的有序的,
     * 所以找到第一个比自己小的位置就可以停下来,执行插入,再往前一定也是比自己小的。
     * 比如: 1256 487(为了方便看,我打了空格),现在我们操作‘4’,将4和‘6’比较,发现比自己大,继续向前,和‘5’比较,发现比自己大,继续向前,
     * 和‘2’比较,发现比自己小,将‘4’放在‘2’后面,对‘4’的操作结束,后面的以此类推,最终数组就是有序的了。
     *
     * */
    public static void charu(int[] arr) {
        for (int i = 1, len = arr.length; i < len; i++) {
            int temp = arr[i];
            int index = i;
            for (int j = i; j > 0; j--) {
                if (temp < arr[j - 1]) {
                    arr[j] = arr[j - 1];
                    index = j - 1;
                }
            }
            arr[index] = temp;
        }
    }

    /*
     * 方法:希尔排序
     * 时间复杂度:O(n²)
     * 思路:希尔排序是插入排序的修改版本,所以核心的地方是一样的。
     * 不一样的是,它不再是从头开始逐渐在左边寻找合适的位置插入。在找位置插入之前,它先将数组/2得到两个小数组a b,
     * 然后遍历后面的数组比较b0和a0,把小的放前面,继续循环b1和a1....直到对比了b的所有的值。拿数组5, 2, 8, 9, 1, 3,4来说,
     * 数组长度为7,当increment为3时,数组分为两个序列
     * 5,2,8和9,1,3,4,第一次排序,9和5比较,1和2比较,3和8比较,4和比其下标值小increment的数组值相比较(向前一个步长的比较)
     * 此例子是按照从小到大排列,所以大的会排在后面,第一次排序后数组为 4,1,3,5,2,8,9。接下来,将数组再除以2划分。
     * 此时是7/4=1,步长是1,所以数组分为 4 1 3 5 2 8 9,每个都是单独,从第二个数字(索引1)开始,取出来向前逐个比较,
     * 找到比自己小的位置,执行插入,然后执行下一个数组,因为再往前一定也是比自己小的。这一步和插入排序是一模一样的。
     *
     * */
    public static void shell(int[] arr) {
        for (int step = arr.length / 2; step > 0; step /= 2) {
            for (int i = step; i < arr.length; i++) {
                int temp = arr[i];
                int index = i;
                for (int j = i; j >= step; j -= step) {
                    if (temp < arr[j - step]) {
                        arr[j] = arr[j - step];
                        index = j - step;
                    }
                }
                arr[index] = temp;

            }
        }

    }
    
}

 

おすすめ

転載: blog.csdn.net/u013821237/article/details/89886091