首页 > 编程语言 >排序算法-插入排序

排序算法-插入排序

时间:2023-04-15 15:35:42浏览次数:40  
标签:Sort Insert insertIndex nums 插入排序 gap 算法 排序

排序算法-插入排序

1. 直接插入排序Insert Sort

直接插入排序.gif

1.1 Insert Sort介绍

Insert Sort也是一种简单的内部排序算法,其是对待排序的元素以插入的方式寻找该元素的适当位置,以达到排序的目的,是一种稳定的排序算法。

Inser Sort的基本思想是:将待排序序列看作一个有序表一个无序表初始时有序表仅包含一个元素,而无序表中包含n - 1个元素。排序的过程中每次取无序表中的第一个元素,将其依次与有序表中的元素进行比较,把它插入到有序表中的适当的位置,建立一个新的有序表,每轮排序都使得有序表长度 + 1无序表长度 - 1

1.2 图解说明Insert Sort步骤

举一个例子来具体说明直接插入排序法的过程。给出一个无序数列:55,85,21,12,5使用直接插入排序将其排列成一个从小到大的有序数列。

直接插入排序示例.png

  1. 定义两个临时变量insertValueinsertIndex分别表示待插入元素该待插入元素想要要插入的位置
  2. 第一轮Insert Sort排序,nums[0] == 55 为有序区,选择无序区的第一个元素inserValue = nums[1] == 85,inserIndex = 0,与有序区中的元素比较,nums[1] > nums[0],不需要往前插入,也即找到了nums[1]应插入的位置(就是原本nums[1]的位置),将nums[1]并入有序区;
  3. 第二轮,选择无序区的第一个元素insetValue = nums[2] == 21,insertIndex = 1,逐一与有序区的元素比较,发现nums[2] < nums[1],首先将num[1]的值后移,并令insertIndex--(insertIndex == 0),再次进行比较,nums[2] < nums[0],将nums[0]的值后移同时insertIndex--(insertIndex == -1),此时找到了nums[2]应插入的位置(即应插入到nums[0]的位置)进行插入;
  4. 重复执行上述过程,每一轮都使得有序区长度 + 1,无序区长度 - 1,直至无序区元素全部插入完毕。

1.3 Insert Sort时间复杂度分析

  • 最好情况时间复杂度:O(n)

    最好情况下即数组本身就是按序排列,那么每趟排序都只进行一次比较,不需要移动元素。

  • 最坏情况时间复杂度:O(\(n^2\))

    最坏情况下每趟排序都要与前面的元素进行比较且每次比较都要移动元素。

  • 平均时间复杂度:O(\(n^2\))

1.4 代码实现

package com.algorithm;

import java.util.Arrays;

/**
 * @author SnkrGao
 * @create 2023-04-14 19:27
 */
public class InsertSort {

    public static void main(String[] args) {
        int[] nums = {6,1,9,2,3,7,19,15};
        System.out.println("排序前的数组为:");
        System.out.println(Arrays.toString(nums));
        System.out.println("---------------------------------");

        insertSort(nums);

        System.out.println("---------------------------------");
        System.out.println("排序后的数组为:");
        System.out.println(Arrays.toString(nums));

    }

    public static void insertSort(int[] nums) {

        // 初始时有序区长度为1,因此无序区应从nums[1]开始
        for (int i = 1; i < nums.length; i++) {
            int insertValue = nums[i]; // 表示待插入元素
            int insertIndex = i - 1; // 表示该待插入元素初始时想要插入的位置,因为insertValue要与前一个元素比较

            while (insertIndex >= 0 && insertValue < nums[insertIndex]) {
                // 满足比较的条件,就要将nums[insertIndex]后移,并继续向前比较
                nums[insertIndex + 1] = nums[insertIndex];
                insertIndex--;
            }

            // 循环退出,找到insertValue应插入的位置为insertIndex + 1,因为在循环中执行了insertIndex--
            nums[insertIndex + 1] = insertValue;

            System.out.println("第" + i + "轮排序结果为:");
            System.out.println(Arrays.toString(nums));
        }
    }
}

2. 希尔排序Shell Sort

希尔排序.gif

2.1 Shell Sort介绍

Shell Sort是希尔于1959年提出的一种排序算法,Shell Sort也是一种插入排序算法,其是对直接插入排序的一种改进,引入了增量(gap)的概念,也称为缩小增量排序。Shell Sort是一种不稳定的排序算法。

Shell Sort的基本思想是:Shell Sort可以与Insert Sort类比来理解,Shell Sort采用了跳跃式分组的概念,通过某个增量gap将待排序序列分为若干组,然后分组进行Insert Sort,每一轮所有分组的Insert Sort执行完毕后,逐步缩小gap,继续按组进行Insert Sort操作,直至gap为1时,整个序列被分为一组,此时序列已达到宏观上的基本有序再执行一轮Insert Sort完成排序算法终止

说明:

  1. Shell Sort是Insert Sort的改进版,Shell Sort会执行多轮Insert Sort
  2. Shell Sort每轮执行Insert Sort时与单纯的Insert Sort有区别,其不是一个挨一个地比较插入,而是隔几个元素(gap)比较插入一次,这个gap不是固定的,而是逐渐缩小的,即每轮执行的Insert Sort增量都不一样;
  3. Shell Sort有两种实现方法:交换式移位式,但交换式会出现多次元素交换,造成很大程度的时间浪费,本文主要介绍效率较高的移位式,实际上交换式和移位式的基本思想是一致的。

2.2 图解说明Shell Sort步骤

举一个例子来具体说明希尔排序法的过程。给出一个无序数列:8,9,1,7,2,3,5,4,6,0使用希尔排序将其排列成一个从小到大的有序数列。

希尔排序示例.png

2.3 代码实现

package com.algorithm;

import java.util.Arrays;

/**
 * @author SnkrGao
 * @create 2023-04-15 15:03
 */
public class ShellSort {

    public static void main(String[] args) {
        int[] nums = {8,9,1,7,2,3,5,4,6,0};
        System.out.println("排序前的数组为:");
        System.out.println(Arrays.toString(nums));

        shellSort(nums);

        System.out.println("排序后的数组为:");
        System.out.println(Arrays.toString(nums));
    }

    public static void shellSort(int[] nums) {

        // 增量gap初始为nums.length / 2,并逐渐减少,当gap == 1时执行最后一轮算法结束
        for (int gap = nums.length / 2; gap > 0; gap /= 2) {
            // 下面的代码类比直接插入排序,原理是一致的,只是考虑gap增量,隔几个元素进行比较交换
            for (int i = gap; i < nums.length; i++) {
                int insertValue = nums[i];
                int insertIndex = i - gap;

                while (insertIndex >= 0 && insertValue < nums[insertIndex]) {

                    nums[insertIndex + gap] = nums[insertIndex];
                    insertIndex -= gap;
                }

                nums[insertIndex + gap] = insertValue;
            }
        }
    }
}

2.4 Shell Sort时间复杂度分析

可以看出Shell Sort的时间复杂度与gap增量序列的设计有很大关系,不同的gap序列对应着不同的时间复杂度,因此对其时间复杂度的分析非常复杂。

最好情况时间复杂度:O(n)

最坏情况时间复杂度:O(\(n^2\))

平均时间复杂度:O(\(nlong^2n\))

标签:Sort,Insert,insertIndex,nums,插入排序,gap,算法,排序
From: https://www.cnblogs.com/SnkrGao/p/17321211.html

相关文章

  • 虾皮API接口根据关键词取商品列表(商品详情,库存,排序,价格...)返回值及说明
    参数说明通用参数说明version:API版本key:调用key,测试key:test_api_keyapi_name:API类型[item_search,item_get]cache:[yes,no]默认yes,将调用缓存的数据,速度比较快result_type:[json,xml,serialize,var_export]返回数据格式,默认为jsonlang:[cn,en,ru]翻译语言,默认cn简体中......
  • 虾皮API接口根据关键词取商品列表(商品详情,库存,排序,价格...)返回值及说明
    参数说明通用参数说明version:API版本key:调用key,测试key:test_api_keyapi_name:API类型[item_search,item_get]cache:[yes,no]默认yes,将调用缓存的数据,速度比较快result_type:[json,xml,serialize,var_export]返回数据格式,默认为jsonlang:[cn,en,ru]翻译语言,默认cn简体中文API:i......
  • 【故障诊断】基于KNN、SVM、RF、DT、ET多种算法实现制冷系统故障诊断附Matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 【锂电池健康状态预测】基于布谷鸟算法优化BP神经网络实现锂电池健康状态预测附含Matl
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 数组元素排序(二)
    快速排序(QuickSort)由图灵奖获得者TonyHoare发明,被列为20世纪十大算法之一,是迄今为止所有内排序算法中速度最快的一种,快速排序的时间复杂度为O(nlog(n))。快速排序通常明显比同为O(nlogn)的其他算法更快,因此常被采用,而且快排采用了分治法的思想,所以在很多笔试面试中能经常看到快......
  • 算法-并查集-200
    publicclassSolution{publicintNumIslands(char[][]grid){if(grid==null||grid.Count()==0)return0;introwCount=grid.Count();intcolCount=grid[0].Count();intwaters=0;UnionFinduf=newUnionFind(grid);for......
  • 排序复杂度
    常见的排序算法中,效率高到低的排名如下:1.快速排序(QuickSort):时间复杂度平均情况下为O(nlogn),是最快的排序算法之一。2.归并排序(MergeSort):时间复杂度稳定为O(nlogn),但需要消耗额外的内存空间。3.堆排序(HeapSort):时间复杂度为O(nlogn),实现简单,不需要额外的内存空间。4.希......
  • leetcode:排序数组
    题目描述给你一个整数数组 nums,请你将该数组升序排列。示例1:输入:nums=[5,2,3,1]输出:[1,2,3,5]示例2:输入:nums=[5,1,1,2,0,0]输出:[0,0,1,1,2,5]题目地址:912.排序数组解题思路 这道题目直接告诉你了要排序,关键是选中什么样的排序算法?题目的限制条件是有两个,第......
  • 算法-丑数2-构造小根堆
    intNthUglyNumber(intn){if(n==1)return1;List<long>arr=newList<long>();//这里用list,它会自己扩容,用数组就需要自己操作这些了arr.Add(1);int[]uglyArr={2,3,5};HashSet<long>hs=newHashSet<long>();hs.Add(1);......
  • 《Python算法交易实战》——yfinace获取yahoo财经数据
    因为从2021年11月1日起,用户无法从中国大陆地区使用Yahoo产品与服务所以下面两个错误,都是代理配置的问题error:Notimezonefound,symbolmaybedelistederror:Nodatafoundforthisdaterange,symbolmaybedelisted以下是解决办法:1.实现强劲上网,保证你可以在浏览器......