三种常用的插入排序算法--直接插入排序、二分插入排序、希尔排序

本文介绍了三种插入排序算法:直接插入排序、二分插入排序及希尔排序,并提供了Java实现代码。直接插入排序简单直观但效率较低;二分插入排序通过二分查找提高插入效率;希尔排序则通过分组减少比较次数,提高了整体性能。

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

本文介绍三种常用的插入排序算法:

1、直接插入排序算法 复杂度o(n^2)

2、二分插入排序算法(在直接插入排序的基础上使用二分查找优化了插入点的查找效率) 最好o(nlog2(n)) 最差o(n^2)

3、希尔排序算法(利用直接插入排序的一些特点设计的一种排序算法) 大约为o(n^1.3)


下面用java代码来说明思路

1、直接插入排序:

public class Ranker {
    //直接插入排序 稳定 复杂度o(n^2) 只需要一个元素的辅助空间用于交换 因此也称为原地(In Place)排序算法
    private static void DirectlyInsertSort(int[] arr){
        /*
         * 对n个元素 由n-1次排序组成,第i趟是将第i+1个元素个元素插入到前面的i个元素中去
         * 第i趟完成之后前i+1个元素都是有序的
         * */
        int i = 0 , j = 0;
        for(i = 1; i<arr.length ; i++){//从第1个元素开始一趟一趟地插入元素 第i趟插入之后 要保证前i个元素有序
            int temp = arr[i];//待插入元素
            for(j = i - 1; j >= 0 && arr[j] > temp ; j--){//第i个元素temp与前面元素进行比较直到比到头或者找到一个元素比他小
                arr[j+1] = arr[j];//如果arr[j]比temp大,就一直往后移 直到找到一个合适第i个元素的位置
            }
            arr[j+1] = temp;//找到了相应的位置j+1 放进去 因为第j号元素不满足arr[j]>temp 所以放在arr[j+1]
        }
    }
}

原理上就是对n个元素进行n-1次排序,第i趟将第i+1个元素插入到前面的i个元素中去,第i趟完成之后保证前i+1个元素都是有序的,是稳定的排序算法,复杂度o(n^2)。


2、二分插入排序算法:

public class Ranker{
    private static void BinaryInsertSort(int[] arr){
        /*
         * 和直接插入思路基本一致 只不过是用二分法来找第i+1个元素的插入位置 left就是这个元素需要放入的位置
         * */
        int left,right,mid = 0,i,j;
        for( i = 1; i<arr.length ; i++ ){//从第1个元素开始一趟一趟地插入元素 第i趟插入之后 要保证前i个元素有序
            int temp = arr[i];//待插入元素
            left = 0;//查找范围左端
            right = i-1;//查找范围右端
            while(left<=right){//只要left不要出现在right右端 算法都可以继续
                mid = (left+right)>>1;//找到left和right的中间点
                if(arr[mid]>temp)
                    right = mid - 1;//缩小查找范围到[left,mid-1]
                else
                    left = mid + 1;//缩小查找范围到[mid+1,right]
            }//循环结束时left出现在了right的右边 这个时候[0,right]是比temp小的,而[left,i]是比temp大的数 
            for( j = i-1 ; j >= left ; j-- ){
                arr[j+1] = arr[j];//将比temp大的元素统统往后移一位
            }
            arr[left] = temp;//在arr[left]这个地方放下temp元素即可
        }
    }
    
}

这个的思路和直接插入排序思路大体一致,关键在于在第i趟插入元素的时候,查找应该插入的位置的时候使用了二分法进行查找。


3、希尔排序算法:

public class Ranker{
    //希尔排序 利用直接插入排序的一些特点做出了改进 复杂度大约在o(n^1.3) 不稳定
    public static void ShellSort(int[] arr){
        /*
         * 将待排序列划分为若干子序列分别进行直接插入排序 待整个序列的数据基本有序后,再进行一次直接插入排序
         * 相当于每一次排序之后都要缩小子序列的增量
         * */
        int d = arr.length >> 1;//增量 初始值为数组长度的一半
        while(d>=1){//增量小于1退出 注意等号 d=1的时候仍然要进行排序 而且是最后一次排序
            for(int k = 0; k<d ; k++){//遍历所有子序列
                for( int i = k+d ; i<arr.length ;i+=d){ //对每个子序列直接插入
                    int temp = arr[i];//存放这个子序列的这次插入的第i个元素
                    int j = 0;
                    for(j = i - d ;j >= k && arr[j] > temp ; j-=d){
                        arr[j+d] = arr[j];
                    }
                    arr[j+d] = temp;//找到temp适合的位置 放下这个元素
                }
            }
            d >>=1;//较小增量 减为上次的一半
        }
    }
}

希尔排序算法是利用直接插入排序算法特点做出的一些改进,将整个序列分成若干个子序列分别进行直接插入排序,逐渐减小每个子序列的增量,直到增量等于1,使得整个序列逐渐趋于有序,最后当增量等于1的时候对整个基本有序的序列进行排序,整个算法复杂度大约在o(n^1.3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值