• 插入排序


    直接插入排序

    将待排序序列分为有序区和无序区,将无序区的元素逐一插入到有序区合适的位置上,直到全部有序

    类似玩牌时整理排的过程。

    直接插入排序步骤

    1.以数组第一个元素为有序区。

    2.将无序区的第一个元素关键码,插入到有序区。

    • 寻找关键码在有序区的目标位置
    • 插入关键码

    重复步骤2,直至全部有序。

    直接插入排序演示

    clip_image001

    算法分析

    clip_image002

    直接插入排序-java实现

        /**
         * 直接插入排序的分步理解
         * 
         * @param arr
         */
    
        public static void straightInsertionSort_step(int[] arr) {
            int size = arr.length;
            for (int i = 1; i < size; i++) { // arr[i]为关键码
                int destIndex = 0; // 插入的目标下标
                int key = arr[i]; // 保存关键码
                // 遍历寻找destIndex
                for (int j = i - 1; j >= 0; j--) {
                    if (arr[j] <= key) { // 如果关键码>=序区元素j,则插入j之后,否则,插入0下标
                        destIndex = j + 1;
                        break;
                    }
                }
                // 后移记录
                for (int j = i - 1; j >= destIndex; j--) {// 从前向后会覆盖
                    arr[j + 1] = arr[j];
                }
                // 插入
                arr[destIndex] = key;
                System.out.print("第 " + i + "轮 :" + Arrays.toString(arr));
                System.out.println("	destIndex:" + destIndex);
            }
        }
    
        /**
         * 直接插入排序
         * 
         * @param arr
         */
        public static void straightInsertionSort(int[] arr) {
            int size = arr.length;
            for (int i = 1; i < size; i++) {         // 外层控制轮数
                int key = arr[i];             // arr[i]为关键码
                int j = i - 1;
                for (; j >= 0 && key < arr[j]; j--){    //如果关键码>=序区元素j,则插入j之
                    arr[j + 1] = arr[j];        // 在寻找关键码插入位置的同时将元素后移
                }
                arr[j + 1] = key;             // 插入目标位置
                System.out.print("第 " + i + "轮 :" + Arrays.toString(arr));
                System.out.println("	destIndex:" + (j + 1));
            }
        }
    

    希尔排序

    希尔排序是对直接插入排序的一种改进,着眼于:

    • 若排序记录按关键码基本有序,直接插入排序的效率很高
    • 记录个数少,直接插入排序效率高。因为直接插入排序时间复杂度为O(n^2),n越小,效率越高。

    希尔排序思想:

    • 把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。保证整个序列基本有序。
    • 随着步长逐渐减小,所分成的序列包含的记录越来越多,当步长的值减小到 1 时,所有记录合成为一组,经过直接插入排序后,构成一组有序记录,则完成排序。

    开始时增量的取值较大,每个子序列记录个数少,排序效率较高;后来增量逐步缩小,每个子序列中的记录个数增加,但已经基本有序,故排序效率也较高。

    希尔排序演示:

    clip_image003

    算法分析

    clip_image004

    希尔排序-java实现

        /**
         *     “把记录按步长 gap分组,对每组记录采用直接插入排序方法进行排序。保证整个序列基本有序.”<br>
         * @param arr
         */
        public static void shellSort(int[] arr) {
            int size = arr.length;
            //把下标增量为gap的记录编为一个子序列
            //增量逐步减小,直到整个序列的子序列为本身,即增量gap=1
            for (int gap = size / 2; gap >= 1; gap /= 2) {
                //对子序列进行直接插入排序
                for (int i = gap; i < size; i++) {
                    int key = arr[i];
                    int j = i - gap;
                    for (; j >= 0 && key < arr[j]; j -= gap) {
                        arr[j + gap] = arr[j];
                    }
                    arr[j + gap] = key;
                }
                System.out.println("gap: " + gap + " :" + Arrays.toString(arr));
            }
        }
    
  • 相关阅读:
    软件工程个人作业02
    第三周学习进度条
    《构建之法》阅读笔记01
    第二周学习进度条
    软件工程个人作业01
    大道至简第三章读后感
    动手动脑课后实践
    JAVA数字想加并输出
    大道至简第二章读后感
    大道至简读后感
  • 原文地址:https://www.cnblogs.com/klguang/p/5427132.html
Copyright © 2020-2023  润新知