• 【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)


    插入排序基本思想

    每次将一个待排序的记录按其keyword大小插入到前面已经拍好序的子文件的适当位置,直到全部记录插入完毕为止。

    直接插入排序

    基本思想

    直接插入排序的基本操作是将一个记录插入到已排好序的有序表中。从而得到一个新的有序表。即如果待排序的记录存放在数组R[1······n]中,排序过程中,R被分成两个子区间R[1······i]和R[i+1······n],当中。R[1······i]是已经排好序的有序区;R[i+1······n]是当前未排序的部分。

    将当前无序区的第一个记录R[i+1]插入到有序区R[1······i]的适当位置,使R[1······i+1]变为新的有序区,每次插入一个数据,直到全部的数据有序为止。

    java程序

    /*************************
    * 
    * 直接插入排序
    *
    *************************/
    public class InsertSort {
    
    private void insertSort(int[] datas) {
        if (datas == null || datas.length < 2)
            return;
        int i, j, insertData;
        for (i = 1; i < datas.length; i++) {
            insertData = datas[i];// 要插入的变量
            for (j = i - 1; j >= 0 && insertData < datas[j]; j--)
                datas[j + 1] = datas[j];
            datas[j + 1] = insertData;// 将要插入的数据放置到正确的位置
        }
    }
    
    public static void main(String[] args) {
        int[] datas = new int[] { 6, 5, 3, 1, 8, 7, 2, 4 };
        System.out.println("********排序前********");
        for (int i = 0; i < datas.length; i++) {
            System.out.print(datas[i] + ",");
        }
        InsertSort insertSort = new InsertSort();
        insertSort.insertSort(datas);
        System.out.println("
    ********排序后********");
        for (int i = 0; i < datas.length; i++) {
            System.out.print(datas[i] + ",");
        }
    }
    
    }
    

    性能分析

    1. 时间复杂度

    1. 直接插入排序属于就地排序,是一种稳定的排序方法。

    希尔排序

    基本思想

    先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组,全部距离为d1的倍数的记录放在同一个组中,在各组内进行插入排序;然后。取第二个增量d2 < d1,反复上述的分组和排序,直至所取得增量dt = 1(dt < dt-1 < ······ < d2 < d1),即全部记录放在同一个组中进行直接插入排序为止。

    java程序

    /*************************
    * 
    * 希尔排序
    *
    *************************/
    public class ShellSort {
    
    private void shellSort(int[] datas) {
        if (datas == null || datas.length < 2)
            return;
        int temp;// 暂存变量
        int dataLength;// 步长
        int pointer;// 进行处理的位置
        dataLength = datas.length / 2;// 初始化步长
        while (dataLength != 0) {
            for (int j = dataLength; j < datas.length; j++) {
                temp = datas[j];
                pointer = j - dataLength;
                while (pointer >= 0 && temp < datas[pointer]) {
                    datas[pointer + dataLength] = datas[pointer];
                    pointer = pointer - dataLength;
                }
                datas[pointer + dataLength] = temp;
            }
            dataLength = dataLength / 2;
        }
    }
    
    public static void main(String[] args) {
        int[] datas = new int[] { 6, 5, 3, 1, 8, 7, 2, 4 };
        System.out.println("********排序前********");
        for (int i = 0; i < datas.length; i++) {
            System.out.print(datas[i] + ",");
        }
        ShellSort shellSort = new ShellSort();
        shellSort.shellSort(datas);
        System.out.println("
    ********排序后********");
        for (int i = 0; i < datas.length; i++) {
            System.out.print(datas[i] + ",");
        }
    }
    
    }
    

    性能分析

    希尔排序的运行时间依赖于增量序列(步长)的选取。好的增量序列有例如以下特点:

    1. 最后一个增量必须为1
    2. 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。

    希尔排序的时间性能要因为直接插入排序,原因例如以下:

    • 当文件初态基本有序时直接插入排序所需的比較和移动次数均较少。
    • 在希尔排序開始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐降低。而各组的记录数目逐渐增多,但因为已经按di-1作为距离排过序,使文件较接近于有序状态。所以新的一趟排序过程也较快。

      因此,希尔排序在效率上较直接插入排序有较大的改进。

    希尔排序是一种不稳定的排序方法

    參考资料:《数据结构与算法分析——java语言描写叙述》、《大话数据结构》

  • 相关阅读:
    B01-java学习-阶段2-面向对象
    A11-java学习-二维数组-面向对象概念-类的编写-测试类的编写-创建对象-使用对象-递归
    09-java学习-数组-冒泡排序-选择排序-数组工具类编写-查找-扩容
    08-java学习-数组-增强for循环-数组与方法-main函数参数
    07-java学习-方法重载-idea集成开发工具学习-项目-模块-包
    执行SQL语句---SELECT
    执行SQL语句---INSERT/UPDATE/DELETE
    undefined reference to `mysql_init'解决办法
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    网络编程(三)---数据报套接字
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7265229.html
Copyright © 2020-2023  润新知