插入排序的三种算法(Java代码实现)

目录

 

插入排序:    

        基本思想:

1:直接插入排序:

        基本思想:

        过程:

2:折半插入排序:

        基本思想:

        过程:

3:希尔排序:

        基本思想:

        过程:


 

插入排序:   

基本思想:

        每一趟将一个待排序的数,按照它的大小插入到已经排好序的一组数组的适当位置上,直到所有数排序完成。例如你斗地主会理牌吧,过程相同,原理一样。

        根据查找方法的不同,大致分为了三种:1:直接插入排序.2:折半插入排序.3:希尔排序.

1:直接插入排序:

基本思想:

        顾名思义,就是直接把一个数插入到已经排好的有序表中,查找插入位置方法为顺序查找,从而得到一个新的有序表,直到所有数字排序完成。

过程:

       先来看一张图:

e1ac0b37a9554fdc8e7f0a538deadf01.gif

       在实现插入时我们可以选择从小到大比较,也可以选择从大到小比较,图例所示就是从大到小比较的顺序。

代码实现:

import java.util.Arrays;

public class InsertSort {
    public static void main(String[] args){
        int[] a={12,15,9,20,6,31,24};
        Sort(a);//调用方法
    }

    public static void Sort(int[] s){
        for (int i=1;i< s.length;i++){//注意i不能等于数组长度,因为数组下标从零开始而不是从1.
            int temp=s[i];//存储待插入数的数值
            int j;//j必须在此声明,如果在for循环内声明,j就不能拿出for循环使用,最后一步插入就无法执行
            for (j=i-1;j>=0&&temp<s[j];j--){
                s[j+1]=s[j];//如果大于temp,往前移动一个位置
            }
            s[j+1]=temp;//将temp插入到适当位置
        }
        System.out.println(Arrays.toString(s));//输出排好序的数组
    }
}

结果:

3a7d7fa0eb7941ea8d905216c624ecba.png

 时间复杂度:gif.latex?O%28n%5E%7B2%7D%29

 空间复杂度:gif.latex?O%281%29

 算法特点:

     (1):稳定排序。

     (2):算法简便,且容易实现。

     (3):更适合于初始记录基本有序(正序)的情况,初始记录无序,n较大,时间复杂度高,不宜采用。

2:折半插入排序:

基本思想:

        在直接插入排序的基础上,将查找方法从顺序查找改为折半查找,就是在将 将要插入到现有 有序序列的数字寻找适当插入位置的比较次数减少了。

过程:

代码实现:

import java.util.Arrays;

public class BinsertSort {
    public static void main(String[] args){
        int[] a={2,6,3,8,1,4,2,7};
        BInsertSort(a);//调用方法
    }

    private static void BInsertSort(int[] s){
        for(int i=1;i<s.length;i++){
            int temp=s[i];//保存要插入的数的数值
            int low=0;//设置查找区间初始值 下区间值
            int high=i-1;//上区间值
            while(low<=high){//查找结束条件
                int mid=(high+low)/2;//折半,中间值
                if(s[mid]>temp){//待插入值小于中间值
                    high=mid-1;//上区间值变为中间值-1
                }
                else {//待插入值大于中间值
                    low=mid+1;//下区间值变为中间值+1
                }
            }
            for (int j=i-1;j>=low;j--){
                s[j+1]=s[j];//将low及low之前的数向前移动一位
            }
            s[low]=temp;//low就是待插入值的适当插入点
        }
        System.out.println(Arrays.toString(s));//输出排好序的数组
    }
}

  结果:

f3f689ff09b84678b7c58dd9579e274a.png

  时间复杂度:gif.latex?O%28n%5E%7B2%7D%29

  空间复杂度:gif.latex?O%281%29

  算法特点:

       (1):稳定排序。

       (2):适合初始记录无序,n较大的情况。

3:希尔排序:

基本思想:

       又称“缩小增量排序”(Diminishing Increment Sort),因D.LShell于1959年提出而得名。实质上是采用分组插入的方法,先将整个待排序数组分割成几组,在对每组采用直接插入排序,然后再增加每组的数据量,重新分组,再直接插入排序,直到增量为1,再对整体进行一次直接插入排序。

过程:

       先来看一张书上的图:

718c9818670e45fa8f096b4379e1ea4e.png

           增量分别为:5,3,1。

 代码实现:

import java.util.Arrays;

public class ShellSort {
    public static void main(String[] args) {
        int[] a={2,6,3,8,1,4,2,7};
        Shellsort(a);//调用方法
    }

    public static void Shellsort(int[] s){
        int zl=s.length/2;//设置增量为数组长度的1/2
        for (;zl>0;zl=zl/2){//增量依次减少为1/2
            for (int i=zl;i<s.length;i++){//对相应增量的数组分组进行直接插入排序
                int temp=s[i];
                int j;
                for (j=i-zl;j>=0&&temp<s[j];j-=zl){//注意这里必须将j的初值设置为i-zl,否则数组下标会出界(也就是为负数)
                    s[j+zl]=s[j];
                }
                s[j+zl]=temp;
            }
        }
        System.out.println(Arrays.toString(s));//输出排好序的数组
    }
}

  结果:

b273f6918a044036a7ecc91a5fcf40a4.png

    时间复杂度:gif.latex?O%28n%5E%7B1.3%7D%29(最好情况) gif.latex?O%28n%28log_%7B2%7Dn%29%5E%7B2%7D%29(最坏情况)

    空间复杂度:gif.latex?O%281%29

    算法特点:

         (1):不稳定排序(数据跳跃式移动)。

         (2):增量有各种取法,最后一个增量值必须为1。

         (3):适合初始记录无序,n较大的情况。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值