zoukankan      html  css  js  c++  java
  • 插入排序(Insertion Sort)

    一、概念

      插入排序是把一个数插入到一组有序数列的合适位置。在实际操作中往往把数组的第一个数看作有序数列,依次将后面的数插入到前面有序数列的合适位置。

    二、排序过程

      假设有一个数组,{99,67,82,43,12,26,18,55},则其从小到大插入排序的执行过程如下:

      第一次循环:{99,67,82,43,12,26,18,55}

      第二次循环:{99,67,82,43,12,26,18,55}

            {67,99,82,43,12,26,18,55}

      第三次循环:{67,82,99,43,12,26,18,55}

      第四次循环:{67,82,43,99,12,26,18,55}

            {67,43,82,99,12,26,18,55}

            {43,67,82,99,12,26,18,55}

      第五次循环:{43,67,82,12,99,26,18,55}

            {43,67,12,82,99,26,18,55}

            {43,12,67,82,99,26,18,55}

            {12,43,67,82,99,26,18,55}

      第六次循环:{12,43,67,82,26,99,18,55}

            {12,43,67,26,82,99,18,55}

            {12,43,26,67,82,99,18,55}

            {12,26,43,67,82,99,18,55}

      第七次循环:{12,26,43,67,82,18,99,55}

            {12,26,43,67,18,82,99,55}

            {12,26,43,18,67,82,99,55}

            {12,26,18,43,67,82,99,55}

            {12,18,26,43,67,82,99,55}

      第八次循环:{12,18,26,43,67,82,55,99}

            {12,18,26,43,67,55,82,99}

            {12,18,26,43,55,67,82,99}

      排序结束。

      

      从上面的排序过程可以看出,插入排序是可以提前结束的,所以理论上,插入排序比选择排序要快。而且插入排序的时间复杂度为O(n*n),是稳定排序。

    三、Java代码实现  

    public class InsertionSort {
    
        public void sort(int arr[]){
            if (null == arr || arr.length<=1){
                return;
            }
            int lenrth = arr.length;
    
            for (int i=1; i<lenrth; i++){
                for (int j=i; j>0&&arr[j-1]>arr[j]; j--){
                    this.exchange(arr, j-1, j);
                }
            }
        }
    
        private void exchange(int[] arr, int i1, int i2){
            int i = arr[i1];
            arr[i1] = arr[i2];
            arr[i2] = i;
        }
    }

      调用sort方法即可实现插入排序。

    四、优化

      仔细看看上面的程序,每次比较都要交换一次数据,这是很影响效率的。那么这些交换可不可以省去呢?答案是可以的。

      下面是优化之后的代码:

    public class InsertionSort {
    
        public void sort(int arr[]){
            if (null == arr || arr.length<=1){
                return;
            }
            int lenrth = arr.length;
    
            for (int i=1; i<lenrth; i++){
                int pacemaker = arr[i];
                int j;
                for (j=i; j>0&&arr[j-1] > pacemaker; j--){
                    arr[j] = arr[j-1];
                }
                arr[j] = pacemaker;
            }
        }
    
        private void exchange(int[] arr, int i1, int i2){
            int i = arr[i1];
            arr[i1] = arr[i2];
            arr[i2] = i;
        }
    }
  • 相关阅读:
    C# 的 TOML 库
    测试龙芯 LoongArch .NET之 使用 FastTunnel 做内网穿透远程计算机
    开源的负载测试/压力测试工具 NBomber
    .NET 6 Preview 6 正式发布: 关注网络开发
    .NET 5.0 Docker 镜像 错误修复方法
    [LeetCode] 1191. K-Concatenation Maximum Sum K次串联后最大子数组之和
    [LeetCode] 1190. Reverse Substrings Between Each Pair of Parentheses 反转每对括号间的子串
    [LeetCode] 1189. Maximum Number of Balloons 气球的最大数量
    [LeetCode] 1187. Make Array Strictly Increasing 使数组严格递增
    [LeetCode] 1186. Maximum Subarray Sum with One Deletion 删除一次得到子数组最大和
  • 原文地址:https://www.cnblogs.com/aston/p/8120297.html
Copyright © 2011-2022 走看看