插入排序(直接插入排序和希尔排序)

一.基本概念

1.概念:

排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。平时的上下文中,如果提到排序,通常指的是排升序(非降序)

2.稳定性

两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序算
法。
下面用一个简单图给大家说明一下:图中给的数据有俩个3,如果排序之后,黑3还在红3之后,那么这样的排序就是稳定的,否则就是不稳定的。
在这里插入图片描述

3.Java常见排序
在这里插入图片描述

二.具体排序代码实现
1.直接插入排序
稳定性(稳定):稳定性排序在排序过程是不会发生跳跃性的交换数据
​ 1.一个稳定的排序可以变成不稳定的排序;
​ 2.一个本身就不稳定的是不可能变成稳定的;

空间复杂度:O(1);
时间复杂度:

最好情况:O(n)数组有序的时候;
最坏情况:最坏情况O(n2)数组无序的时候;
思路:以升序为例
1.首先用i从头开始遍历数组;
2.接着在外面拿一个空间tmp,每一次都把arr[i]放进去;
3.然后定义一个变量j,j的初始值为i-1;
4.比较arr[j]和tmp大小,如果大于tmp,就在j+1位置放入arr[j];
5.一直直到i遍历完数组,也就排好了。

public static void insertsort(int[] arr){
        for(int i = 1;i < arr.length;i++) {
            int tmp = arr[i];
            int j = i-1;
            for (;j >= 0;j--){
                if (arr[j] > tmp) {
                    arr[j+1] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+1] = tmp;
        }
    }

2.希尔排序
稳定性(不稳定)
​ 1.一个稳定的排序可以变成不稳定的排序;

​ 2.一个本身就不稳定的是不可能变成稳定的;

空间复杂度:O(n^1.3) - O(n^1.5) ;

时间复杂度:

最好情况:O(n)数组有序的时候;
最坏情况:最坏情况O(n^2)数组无序的时候;
思路:升序为例
1.希尔排序实际上是对直接插入排序的优化;
2.对一组数据进行分组,比如下图分为5组,gap == 5,从0号位置开始,加gap,从而确定一组里面的元素,下面同种颜色就是一组;
3.然后每一组都用直接插入排序的方法,进行排序;
4.这一次排完,下一次在分为3组,在调用直接插入排序,下一次可以在分2组,也可以直接分一组;
5.一直分组到分为一组排完序,那么就排好序了;
6.那么大家肯定想知道gap怎么选择,大家有没有发现组数都说素数,所以组数根据数据大小,选择适当的素数组,例如下面这组数据有15个元素,就分别分为5,3,1组。

//希尔排序(优化直接插入排序)
    public static void shellsort(int[] arr){
        //1.首先获取组数gqp
        int[] drr = {5,3,1};//定义一个增量数组
        for (int i = 0;i < drr.length;i++){
            shell(arr,drr[i]);
        }
    }
    //直接插入排序
    public static void shell(int[] arr,int gap) {
        for(int i = gap;i < arr.length;i++) {
            int tmp = arr[i];
            int j = i-gap;
            for (;j >= 0;j -= gap){
                if (arr[j] > tmp) {
                    arr[j+gap] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+gap] = tmp;
        }
    }
3.结果测试
public class TestSort {
//直接插入排序
public static void insertsort(int[] arr){
        for(int i = 1;i < arr.length;i++) {
            int tmp = arr[i];
            int j = i-1;
            for (;j >= 0;j--){
                if (arr[j] > tmp) {
                    arr[j+1] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+1] = tmp;
        }
    }
    //希尔排序(优化直接插入排序)将数组进行分组
    public static void shellsort(int[] arr){
        //1.首先获取组数gqp
        int[] drr = {5,3,1};//定义一个增量数组
        for (int i = 0;i < drr.length;i++){
            shell(arr,drr[i]);
        }
    }
 //直接插入排序
    public static void shell(int[] arr,int gap) {
        for(int i = gap;i < arr.length;i++) {
            int tmp = arr[i];
            int j = i-gap;
            for (;j >= 0;j -= gap){
                if (arr[j] > tmp) {
                    arr[j+gap] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+gap] = tmp;
        }
    }
//测试main方法
public static void main(String[] args) {
        //直接插入排序
        int[] arr = {2,3,5,1,6,4};
        insertsort(arr);
        System.out.print("直接插入排序结果: ");
        for (int i = 0;i < arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        //希尔排序
        int[] arr1 = {7,4,9,34,0,8,5,22,55,6,12,33,56,89,77};
        shellsort(arr1);
        System.out.print("希尔排序结果: ");
        for (int i = 0;i < arr1.length;i++){
            System.out.print(arr1[i]+" ");
        }
        System.out.println();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值