• 插入排序java版


    基本思想:每趟将一个带排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,知道所有待排序的记录全部重新插入为止。

    根据查找方法的不同,分为直接插入排序、折半插入排序和希尔排序。

    直接插入排序是最简单的一种,其基本操作是将一条记录插入到已经排序号的有序列表中,从而得到一个新的、记录数增1的有序表。

    public class InsertSort {
        
        public static void main(String[] args) {
            int[] array = new int[]{2, 6, 3, 8, 9, 0, 1, 7, 4};
            InsertSort(array);
        }
        
        public static void printArray(int[] array) {
            for(int i : array) {
                System.out.printf("%d	", i);
            }
            System.out.println();
        }
        
        public static void InsertSort(int[] array) {
            if( array == null) {
                return;
            }
            
            for (int i = 1; i < array.length; i++) {
                if( array[i] < array[i - 1]) {
                    int key = array[i];
                    int j;
                    for ( j = i - 1; j >= 0; j--) {
                        if ( key < array[j]) {
                            array[j + 1] = array[j];
                        } else {
                            break;
                        }
                    }
                    array[j + 1] = key;
                }
                printArray(array);
            }
        }
    }

    时间复杂度: O(n2)

    空间复杂度:O(1)

    算法特点:

    1. 稳定排序
    2. 算法简单,容易实现
    3. 适用于与链式表结构
    4. 更适合初始记录基本有序的情况,当初始记录无序且n较大时,此算法时间复杂度高,不宜采用。

    折半插入排序,用折半查找法来查找当前记录在以排好的序列中的插入位置,由此进行的插入排序称之为折半插入排序

    public class BInsertSort {
        public static void main(String[] args) {
            int[] array = new int[]{2, 6, 3, 8, 9, 0, 1, 7, 4};
            BInsertSort(array);
        }
        
        
        public static void BInsertSort(int[] array) {
            printArray(array);
            
            for (int i = 1; i < array.length; i++) {
                int key = array[i];
                int low = 0, high = i - 1;
                while(low <= high) {
                    int mod = (low + high) / 2;
                    if (key < array[mod]) {
                        high = mod - 1;
                    } else {
                        low = mod + 1;
                    }
                }
                
                for (int j = i-1; j >= high + 1; j--) {
                    array[j+1] = array[j];
                }
                array[high + 1] = key;
                printArray(array);
            }
            
        }
        
        
        public static void printArray(int[] array) {
            for(int i : array) {
                System.out.printf("%d	", i);
            }
            System.out.println();
        }
    }

    算法时间复杂度:从时间上比较,折半查找比顺序查找快,所以就平均性能来说,折半插入排序优先于直接插入排序,在平均情况下,折半插入排序仅减少了关键字间的比较次数,而记录的移动次数不变,因此,折半插入排序的事件复杂度任为O(n2)

    空间复杂度:折半插入排序所需附加存储空间和直接插入排序相同,只需要一个记录的辅助空间,所以空间复杂度任为O(n2)

    算法特点:

    1. 稳定排序
    2. 因为进行折半查找,所以只能用于顺序结构,不能用于链式结构
    3. 适合初始记录无序,n较大时的情况

     希尔排序又称缩小增量排序,是插入排序的一种。直接插入排序,当待排序的记录个数较少而且排序序列基本有序时,效率较高。希尔排序基于这两点,对直接插入排序进行改进。

    希尔排序实质是采用分组插入的方法,先将整个待排序的记录序列分割成几组,从而减少参与直接插入排序的数据量,对每组分别进行直接插入排序,然后增加每组的数据量,重新分组。这样经过几次分组排序后,整个序列中的记录“基本有序”时,再对全体记录进行一次插入排序。

    希尔对记录的分组,不是简单地“逐段分割”,而是将相隔某个“增量”的记录分为一组。算法步骤如下:

    1. 第一趟取增量d1(d1 < n) 把全部记录分成d1组,所有间隔为d1的记录分在同一组,在各个组中进行直接插入排序。
    2. 第二趟取增量d2(d2 < d1),重复上诉的分组和排序。
    3. 依次类推直到增量等于1,所有记录在同一组中进行直接插入排序为止。
        public static void ShellSort(int[] array, int dk) {
            for(int i = dk; i < array.length; i+= 1) {
                if( array[i] < array[i - dk]) {
                    int key = array[i];
                    int j;
                    for ( j = i - dk; j >= 0; j -= dk) {
                        if ( key < array[j]) {
                            array[j + dk] = array[j];
                        } else {
                            break;
                        }
                    }
                    array[j + dk] = key;
                }
                printArray(array);
            }
        }
        
        public static void ShellSort(int[] array, int[] dt) {
            printArray(array);
            for(int d : dt) {
                ShellSort(array, d);
            }
        }

    时间复杂度:O(n3/2)

    空间复杂度:O(1)

    算法特点:

    1. 记录跳跃式移动导致排序方法是不稳定的。
    2. 只能用于顺序结构,不能用于链式结构。
    3. 增量序列可以有各种取法,但应该是增量序列中的值没有除1之外的公因子,并且最后一个增量值必然等于1.
    4. 记录总的比较次数和移动次数都不比直接插入排序要少,n越大,效果越明显。所以适合初始记录无序,n较大时的情况。
  • 相关阅读:
    1 . CentOS 7的yum更换为国内的阿里云yum源
    0. vagrant+vbox创建centos7虚拟机
    git上传到码云和下载到本地
    spring boot udp或者tcp接收数据
    你好,博客园
    使用firdder抓取APP的包
    初见loadrunner
    sublime快捷键大全
    html中行内元素与块级元素的区别。
    html.css溢出
  • 原文地址:https://www.cnblogs.com/maosonglin/p/13671320.html
Copyright © 2020-2023  润新知