插入排序算法

本文详细介绍了三种插入排序算法:直接插入排序、折半插入排序及希尔排序。每种算法都包括了基本思想、代码实现和性能分析等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插入排序算法

一、介绍

1、使用场景

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法。

2、基本思想

插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

二、常用算法

直接插入、折半插入、希尔排序

说明
1. 以下方法最后结果均按照升序排列
2. 用4,2,1,3,7,4,5,8,3,5序列进行测试

1、直接插入

(1)基本思想

将待排序元素x与已排序元素从后向前依次比较,找到小于等于x的元素y的位置,将从y到x之间的元素(不包括x和y)依次后移一位,并将x插入到y元素的后面,即完成一趟排序,再用相同的方法继续完成对后面元素的排序操作即可。

(2)代码实现
public void straightInsertionSort(int[] arr){
    for(int i=1; i<arr.length; i++){
        if (arr[i] < arr[i-1]) {    //与前面元素进行比较
            int temp = arr[i];
            arr[i] = arr[i-1];      //元素后移
            int j = i-2;
            while (j>=0 && temp < arr[j]) { //找到合适的位置
                arr[j+1] = arr[j];      
                j--;
            }
            arr[j+1] = temp;        //插入到合适的位置
        }
        print(arr);                 //每趟结束打印一次数组当前顺序
    }
}
(3)运行结果

这里写图片描述

(4)性能

①稳定性:稳定
②时间复杂度:O(n^2)

2、折半插入排序(二分插入排序)

(1)基本思想

通过折半查找的方式找到待排序元素的合适位置,将相应的元素依次后移,然后再将待排序元素插入,即完成一趟排序操作,再用相同的方式完成对后面元素的排序操作即可。

(2)代码实现
public void binaryInsertionSort(int[] arr){
    for (int i = 1; i < arr.length; i++) {
        //待排序元素小于前面相邻元素,需要移动位置
        if (arr[i] < arr[i-1]) {
            int temp = arr[i];
            arr[i] = arr[i-1];
            //用折半查找的方式找到合适的插入位置
            int low = 0;
            int height = i-2;
            while(low <= height){
                //不用(low+height)/2是为了防止low+height的值发生溢出
                int mid = low+(height-low)/2;
                if (temp < arr[mid]) {
                    height = mid-1;
                }else{
                    low = mid +1;
                }
            }
            //将元素一次后移一位
            for(int j=i-2; j>=height+1; j--){
                arr[j+1] = arr[j];
            }
            arr[height+1] = temp;
        }
        print(arr);
    }
}
(3)运行结果

这里写图片描述

(4)性能

①稳定性:稳定
②时间复杂度:O(n^2)

3、希尔排序(缩小增量排序)

(1)基本思想

将待排序元素以步长d分成若干组,距离为d的元素在同一组,并在组内进行直接插入排序,所有组都完成一次排序以后,缩小步长,并重复动作,直到步长d=1后完成排序。
这里初始步长设置为数组长度的一般,每完成一次排序后,步长变为原来的一半。

(2)代码实现
public static void ShellSort(int[] arr){
    int d = arr.length/2;               //步长
    while (d >= 1) {
        System.out.println("步长为:"+d);
        //每趟按照步长d进行直接插入排序
        for (int i = d; i < arr.length; i+=d) {
            if (arr[i] < arr[i-d]) {
                int temp = arr[i];
                arr[i] = arr[i-d];
                int j = i-2*d;
                while(j>=0 && temp < arr[j]){
                    arr[j+d] = arr[j];
                    j-=d;
                }
                arr[j+d] = temp;
            }
            print(arr);
        }
        d /= 2;
    }
}
(3)运行结果

这里写图片描述

(4)性能

①稳定性:不稳定
②时间复杂度:希尔排序的时效分析很难,有人在大量的试验基础上推出,当n在某个特定范围内,希尔排序所需的比较次数和移动次数约为n^1.3,比较次数和移动次数还依赖于步长因子序列的选取。目前还没有选取最好的步长因子序列的方法,步长因子有取奇数的,也有取质数的,最后一个步长因子必须是1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值