zoukankan      html  css  js  c++  java
  • 排序算法(三) 插入排序

    InsertionSort

    1.动图演示

    1. 动图1

    双层循环,外部循环选择需要与数组中前面元素比较的元素。内层循环,从该选定元素开始 与 该元素左边的元素进行比较。
    如果选定元素小于左边元素 则与之交换位置。直至找到正确的位置,此次内层循环后,左侧部分元素已经有序。

    2.动图2

    动图1的优化版本。每次比较的时候不再与前面的元素交换位置。如果选定元素 比 左边的小,则让左边元素覆盖相邻右边元素。这样减少了许多交换次数,提高了效率。

    2.代码实现

    //测试工具类在这里 https://www.cnblogs.com/paidaxing7090/p/15080493.html
    import 测试工具类.SortTestHelper;
    
    public class InsertionSort2{
    
        // 我们的算法类不允许产生任何实例
        private InsertionSort2(){}
    
        public static void sort(Comparable[] arr){
    
            int n = arr.length;
            for (int i = 0; i < n; i++) {
    
                // 寻找元素arr[i]合适的插入位置
    
                // 写法1
    //            for( int j = i ; j > 0 ; j -- )
    //                if( arr[j].compareTo( arr[j-1] ) < 0 )
    //                    swap( arr, j , j-1 );
    //                else
    //                    break;
    
                //写法2比较精简与写法1 没差别 ,对应动图1
    //            for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--)
    //                swap(arr, j, j-1);
    
                //  写法3 对应动图2
                Comparable e = arr[i];
                int j = i;
                for( ; j > 0 && arr[j-1].compareTo(e) > 0 ; j--)
                    arr[j] = arr[j-1];
                arr[j] = e;
    
            }
        }
        public static void sort(Comparable[] arr,int l,int r){
        	  
               for (int i = l; i <=r; i++) {
    
                   // 寻找元素arr[i]合适的插入位置
    
                   // 写法1 交换元素
    //               for( int j = i ; j > 0 ; j -- )
    //                   if( arr[j].compareTo( arr[j-1] ) < 0 )
    //                       swap( arr, j , j-1 );
    //                   else
    //                       break;
    
                   // 写法2比较精简与写法1 没差别 ,对应动图1
    //               for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--)
    //                   swap(arr, j, j-1);
    
                   // 写法3 对应动图2
                   Comparable e = arr[i];
                   int j = i;
                   for( ; j > l && arr[j-1].compareTo(e) > 0 ; j--)
                       arr[j] = arr[j-1];
                   arr[j] = e;
    
               }
        }
    
        private static void swap(Object[] arr, int i, int j) {
            Object t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    
        // 测试InsertionSort
        public static void main(String[] args) {
            int N0 = 20000;
            Integer[] arr0 = SortTestHelper.generateRandomArray(N0, 0, 100000);
            Integer[] arr = arr0.clone();
            SortTestHelper.testSort("sort.InsertionSort", arr0);
            SortTestHelper.testSort("sort.InsertionSort2", arr);
            int N2 = 40000;
            Integer[] arr2 = SortTestHelper.generateRandomArray(N2, 0, 100000);
            SortTestHelper.testSort("sort.InsertionSort2", arr2);
            return;
        }
    }
    
    

    3.测试结果

    对于同样的数组,可以看到优化后的插入排序效率提升了。同时,优化后的时间复杂度还是在O(n^2)级别。

    4.算法分析

    4.1描述

    插入排序(InsertionSort),一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

    4.2分析


    插入排序的基本思路简单,平均时间复杂度为O(n^2)。但是如果所排序数组是近乎有序的,则它的时间复杂度为O(n),这是高级排序算法也达不到的时间复杂度。显然,对于近乎有序的数组,大部分情况下都不需要移动元素。
    当数组中存在相等元素时,插入排序中不会有操作 改变相等元素的相对位置,所以插入排序是稳定的。

  • 相关阅读:
    解释机器学习模型的一些方法(一)——数据可视化
    机器学习模型解释工具-Lime
    Hive SQL 语法学习与实践
    LeetCode 198. 打家劫舍(House Robber)LeetCode 213. 打家劫舍 II(House Robber II)
    LeetCode 148. 排序链表(Sort List)
    LeetCode 18. 四数之和(4Sum)
    LeetCode 12. 整数转罗马数字(Integer to Roman)
    LeetCode 31. 下一个排列(Next Permutation)
    LeetCode 168. Excel表列名称(Excel Sheet Column Title)
    论FPGA建模,与面向对象编程的相似性
  • 原文地址:https://www.cnblogs.com/paidaxing7090/p/15088809.html
Copyright © 2011-2022 走看看