插入排序以及分析(JAVA)

插入排序

  • 对于少量元素的排序,插入排序是一个有效的算法

插入排序的基本思想:
是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表
附代码(用了单例模式,因为这个类是为了算法算法性能的内部分析的程序做的)
代码分析了移动和比较次数

时间复杂度:

这个算法如果不在内部统计比较和移动的次数,当待排序数组是有序时,是最优的情况,
只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为 O[N]     
但是由于我们要在内部计数,实际上得到的时间复杂度还是O[N],但是比较的次数不再是N-1次了,而是2N-1次,
但是实际应用中,是N-1次            
此处我们记录的是实际应用中的移动次数          
此算法最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1=(N^2-N)/2,
所以,插入排序最坏情况下的时间复杂度为 O[N^2]        

空间复杂度:

O(1)

稳定性分析:

如果待排序的序列中存在两个或两个以上具有相同关键词的数据,排序后这些数据的相对次序保持不变,即它们的位置保持不变,则该算法是稳定的;
如果排序后,数据的相对次序发生了变化,则该算法是不稳定的。关键词相同的数据元素将保持原有位置不变,所以该算法是稳定的
插入排序是稳定的算法
代码:
使用了单例模式,方便在程序内部比较不同算法的移动/比较次数,不需要的删掉就可以
代码中in_order(List list, boolean flag)方法中的list为一个ArryList,flag=true的时候按正序排列,flag=false的时候逆序排列


public  class Insert_sort {
    public static Insert_sort insert_sort;
    private Insert_sort(){}
    private int com_step;
    private int move_step;

    public List<Integer> in_order(List<Integer> list,boolean flag){//flag=true按正序排序 flag=false按逆序排序
        com_step=0;
        move_step=0;
        Integer[] nums=list.toArray(new Integer[0]);//将列表list转为Integer对象数组
        int i,j;
        for( i=1;i<list.size();i++) {//从数组下标为1的位置开始循环
            int temp = nums[i];//辅助变量
            if (flag==true) {
                for (j = i; j > 0; j--) {//从外层循环开始的位置开始,对当前位置的前一个点的数据和辅助变量(外层循环确定的位置)做比较,
                    // 如果当前位置的前一个位置的数据比辅助结点的大,那么将当前结点的位置和其前一个结点的位置交换
                    //若交换,比较步数+1,移动步数+1;若不交换,比较步数+1
                    if (nums[j - 1] > temp) {
                        nums[j] = nums[j - 1];
                        com_step++;
                        move_step++;
                    } else {
                        com_step++;
                        break;
                    }
                }
                if (nums[j] == temp) {
                    continue;
                } else {
                    nums[j] = temp;
                    move_step++;
                }
            }
            else{
                for(i=0;i<list.size();i++){
                    temp=nums[i];
                    for(j=i;j>0;j--){
                        if(nums[j-1]<temp) {
                            nums[j] = nums[j - 1];
                            com_step++;
                            move_step++;
                        }
                        else{
                            com_step++;
                            break;
                        }

                    }
                    if(nums[j]==temp){
                        continue;
                    }
                    else{
                        nums[j]=temp;
                        move_step++;
                    }
                }
            }
        }
        list=new ArrayList<>(Arrays.asList(nums));
        return list;
    }
    public int getCom_step() {
        return com_step;
    }
    public int getMove_step() {
        return move_step;
    }

    public static Insert_sort getInsert_sort(){
        if(insert_sort==null){
            synchronized (Insert_sort.class){
                if(insert_sort==null){
                    insert_sort=new Insert_sort();
                }
            }
        }
        return insert_sort;
    }
}

参考:
常用算法比较与分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值