插入排序和希尔排序

1.插入排序

插入排序的主要思想就是从未排序的序列中一次依次拿出一位插入到已经排好序的序列中去。插入排序的时间复杂度是O(n^2)。

用 [9,6,4,7,8] 这个数组来模拟一下插入排序的过程:

  • 第一步 : 将位置0的元素9视为已排好序的序列,选择位置1的元素6作为待插入的元素。向前遍历,发现6比9小,则将6和9的位置交换,此时序列变为[6,9,4,7,8]。

  • 第二步 : 接着到了元素4,向前遍历,发现4比9小,交换4和9的位置,序列变为[6,4,9,7,8]。再向前遍历,发现4比6小,交换4和6的位置。此时序列变为[4,6,9,7,8]。

  • 第三步 : 接着到了元素7,向前遍历,7比9小,交换7和9。继续,发现7比6大,由于6之前的元素已经排好序并且都小于7,无需向前遍历。此时序列变为[4,6,7,9,8]。

  • 第四步 : 最后一个元素8,很明显和9交换位置,此时序列变为[4,6,7,8,9]。这也就是最终排好序的序列了。

来看一下Java实现的代码:

public class Insert {
    public static int[] sort(int[] arr) {
        int len = arr.length;
        long startTime = System.currentTimeMillis();
        for (int i = 1 ; i < len ; i++) {
            for (int m=i ; m>0 ; m--) {
                if (arr[m] < arr[m-1]) {
                    int temp = arr[m-1];
                    arr[m-1] = arr[m];
                    arr[m] = temp;
                } else {
                    break;
                }
            }
        }
        System.out.println("sort Time = "+(System.currentTimeMillis()-startTime));
        return arr;
    }
}
2.希尔排序

希尔排序是基于插入排序改进得来的。由于插入排序对于已经排好序的数据效率很高。但是如果遇到最坏的情况例如序列[5,4,3,2,1],这种情况每次都要往前插入,并且由于每次只能移动一位,效率很低。

希尔排序对此作出改进,取一个合适增量,根据这个增量,将数据分为几组,对每组的数据各自进行插入排序,再逐步减小增量,直至增量为1,所以希尔排序也叫缩小增量排序法。希尔排序的时间复杂度接近O(n^1.25)。

还是用 [9,6,4,7,8] 这个数组来模拟一下希尔排序的过程:

  • 第一步 : 取数组长度的 1/2 也就是2为增量步长。

  • 第二步 : 以步长为单位将数组分组三组[9,4] ; [6,7] ; [8]。

  • 第三步 : 对每组的数据进行插入排序之后得到[4,6,9,7,8]。

  • 第四步 : 步长再除以2得1,也就是对上面得到的[4,6,9,7,8]进行插入排序,得到最终结果[4,6,7,8,9]。

Java实现代码如下:

public class Shell {
    public static int[] sort(int[] arr){
        int len = arr.length;
        int step = len/2;
        long startTime = System.currentTimeMillis();
        while (step >= 1) {         
            for (int x= 0;x < (len/(len/step)) ; x = x+1) {
                //对每组进行插入排序
                for(int i = x+step ; i<len; i = i+step) {
                    for(int j=i ; j>x ; j = j-step) {
                        if(arr[j] < arr[j-step]) {
                            int temp = arr[j-step];
                            arr[j-step]=arr[j];
                            arr[j] = temp;
                        } else {
                            break;
                        }
                    }
                }
            }
            step = step / 2;
        }
        System.out.println("Shell Time = "+(System.currentTimeMillis()-startTime));
        return arr;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值