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

    插入排序简介

    直接插入排序是一种最简单的插入排序

    直接插入排序,每次将一个新数据插入到有序队列中的合适位置里。

    插入排序:每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,知道全部插入完成。 

    假设有一组无序序列 R0, R1, ... , RN-1。

    (1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。

    (2) 然后,我们要依次把 R1, R2, ... , RN-1 插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 N-1 。

    (3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。

    所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。 

    核心代码

    public void insertSort(int[] list) {
        // 打印第一个元素
        System.out.format("i = %d:	", 0);
        printPart(list, 0, 0);
     
        // 第1个数肯定是有序的,从第2个数开始遍历,依次插入有序序列
        for (int i = 1; i < list.length; i++) {
            int j = 0;
            int temp = list[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置
     
            // 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位
            for (j = i - 1; j >= 0 && temp < list[j]; j--) {
                list[j + 1] = list[j];
            }
            list[j + 1] = temp;
     
            System.out.format("i = %d:	", i);
            printPart(list, 0, i);
        }
    }

    算法分析

    直接插入排序的算法性能

    排序类别

    排序方法

    时间复杂度

    空间复杂度

    稳定性

    复杂性

    平均情况

    最坏情况

    最好情况

    插入排序

    直接插入排序

    O(N2)

    O(N2)

    O(N)

    O(1)

    稳定

    简单

    时间复杂度 

    当数据正序时,执行效率最好,每次插入都不用移动前面的元素,时间复杂度为O(N)。 

    当数据反序时,执行效率最差,每次插入都要前面的元素后移,时间复杂度为O(N2)

    所以,数据越接近正序,直接插入排序的算法性能越好。 

    空间复杂度

    由直接插入排序算法可知,我们在排序过程中,需要一个临时变量存储要插入的值,所以空间复杂度为 1 。

    算法稳定性

    直接插入排序的过程中,不需要改变相等数值元素的位置,所以它是稳定的算法。 

    完整参考代码

    package notes.javase.algorithm.sort;
     
    import java.util.Random;
     
    public class InsertSort {
     
        public void insertSort(int[] list) {
            // 打印第一个元素
            System.out.format("i = %d:	", 0);
            printPart(list, 0, 0);
     
            // 第1个数肯定是有序的,从第2个数开始遍历,依次插入有序序列
            for (int i = 1; i < list.length; i++) {
                int j = 0;
                int temp = list[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置
     
                // 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位
                for (j = i - 1; j >= 0 && temp < list[j]; j--) {
                    list[j + 1] = list[j];
                }
                list[j + 1] = temp;
     
                System.out.format("i = %d:	", i);
                printPart(list, 0, i);
            }
        }
     
        // 打印序列
        public void printPart(int[] list, int begin, int end) {
            for (int i = 0; i < begin; i++) {
                System.out.print("	");
            }
            for (int i = begin; i <= end; i++) {
                System.out.print(list[i] + "	");
            }
            System.out.println();
        }
     
        public static void main(String[] args) {
            // 初始化一个随机序列
            final int MAX_SIZE = 10;
            int[] array = new int[MAX_SIZE];
            Random random = new Random();
            for (int i = 0; i < MAX_SIZE; i++) {
                array[i] = random.nextInt(MAX_SIZE);
            }
     
            // 调用冒泡排序方法
            InsertSort insert = new InsertSort();
            System.out.print("排序前:	");
            insert.printPart(array, 0, array.length - 1);
            insert.insertSort(array);
            System.out.print("排序后:	");
            insert.printPart(array, 0, array.length - 1);
        }
    }

    运行结果 

    排序前:    6    3    3    5    6    3    1    0    6    4    
    
    i = 0:    6    
    
    i = 1:    3    6    
    
    i = 2:    3    3    6    
    
    i = 3:    3    3    5    6    
    
    i = 4:    3    3    5    6    6    
    
    i = 5:    3    3    3    5    6    6    
    
    i = 6:    1    3    3    3    5    6    6    
    
    i = 7:    0    1    3    3    3    5    6    6    
    
    i = 8:    0    1    3    3    3    5    6    6    6    
    
    i = 9:    0    1    3    3    3    4    5    6    6    6    
    
    排序后:    0    1    3    3    3    4    5    6    6    6
  • 相关阅读:
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》资源汇总
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    Windows、Linux、ARM、Android、iOS全平台支持的RTMP推流组件libEasyRTMP库接口调用说明
    简单高效易用Windows/Linux/ARM/Android/iOS平台实现RTMP推送组件EasyRTMPAndroid MediaCodec硬编码流程介绍
    RTSP网络监控摄像头如何实现Windows、Linux、ARM、Android、iOS全平台支持的拉RTSP流推出RTMP直播流?
  • 原文地址:https://www.cnblogs.com/wangxiayun/p/9925180.html
Copyright © 2011-2022 走看看