经典排序之直接插入排序详解

经典排序之直接插入排序详解

【1】直接插入排序排序算法介绍

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。
思想:每一趟将一个待排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,直到所有待排序记录全部插入为止。
适用情况:小规模数据 或 者基本有序的数据

  • 【2】直接插入排序性能分析:

1、空间效率:O(1)
仅使用了常数个辅助单元,因而空间复杂度为O(1)
2、时间效率:O(n)~O(n方)
在排序过程中,要进行n-1趟。每趟操作要与前面的元素的比较,从而它移不移动移动几次。
最好情况为直接n-1趟不用移动,那么就是O(n)
最坏情况,这n-1趟都要移动,每趟都要移动到第一个,也就是倒序的情况,那么时间复杂度
即 1+2+3+…+n-1 ----》最终时间复杂度即为O(n方)
3、稳定性:稳定
由于每次插入元素时总是从后向前比较在移动,因此在写代码的时候可以将插入元素放到与前面有自己相等
元素的下一个,这样就保证了插入的稳定性。因此直接插入排序是稳定的。

public class InsertSort {
    /*
     * 算法大致思想:
     * 即从数组的第二个往后遍历,假设为升序排列,那么第二个与前一个相比
     * 如果第二个比前一个小那么第二个就要往前寻找它要插入的位置,即寻找第二个大于等于哪一个,就往那个元素的下一个插入
     * 如果第二个比前一个大,那么就继续往后遍历寻找自己比前一个小的。
     * 因为这里每次都是将一个元素往前插入,因此遍历到某个元素时,它的前面都是有序的。
     * */
    public static void InsertSort(int a[], int length) {
        int temp = 0;//用于保存往前要插入节点的值
        int j = 0; //用来记录要插入元素的位置
        /*
         * 从数组第二个开始比较
         * */
        for (int i = 1; i < length; i++) {
            //升序排列,若发现遍历的这个比前一个小,那么遍历的这个就需要往前插入
            if (a[i] < a[i - 1]) {
                temp = a[i];//用temp来保存要被插入的结点
                /*
                 * 从遍历元素的前一个开始往回遍历,一开始j记录的就是前一个元素
                 * 然后开始寻找要插入的位置,没往前找一次,那个位置的元素就往后移动。直至找打为止。
                 * 两种情况寻找插入位置的循环结束:
                 * 1、当temp找到比它小的或者相等的元素时,就代表要插入的地方找到了,就跳出循环
                 * 此时j表示的是那个比它小的元素下标,或者和它相等的元素,下标
                 * 而j+1就代表它的下一个位置,也即代表要插入的位置,同时这个也保证了插入的稳定性。
                 * 2、当遍历到j=0时,依然没有找到,说明目前temp是数组前面最小的元素了,那么得temp放到数组的第一个位置
                 * 那么下一次j=-1跳出循环,然后j+1就代表数组的一个位置,将temp赋给数组j+1那个位置
                 *
                 * 【注1】这里是如何保持稳定性的?
                 * 这是在寻找要插入元素位置时,如果遍历到temp和往前遍历的那个元素相等,那么也就停止循环
                 * 此时j指向的是和temp相等的,j+1代表它的下一个,此时temp放到j+1的那个位置上去
                 * 【注2】临界情况,数组为空或者数组为1一个元素,怎么实现排序?
                 * 如果数组为空或者数组为1个元素,那么在第一个for循环里就已经跳出了循环
                 * */
                /* 【注意】在写代码时:
                 * 下面for循环在写结束条件时,这里有个&&运算。
                 * 这里注意必须将j >= 0放在前面,电脑会先执行&&的前面的内容
                 * 如果j >= 0放在&&后面,当j=-1时电脑还会判断temp < a[j],但a[-1]不存在
                 * 因此程序回显示ArrayIndexOutOfBoundsException-数组下界异常
                 * */
                for (j = i - 1; j >= 0 && temp < a[j]; j--) {
                    a[j + 1] = a[j];//当前遍历的这个元素往后移动
                }
                a[j + 1] = temp; //j+1代表要插入元素的位置
            }
        }
    }
}

运行截图:
经典排序之直接插入排序详解_第1张图片





你可能感兴趣的:(排序算法,数据结构,排序算法)