zoukankan      html  css  js  c++  java
  • 直接插入排序

    直接插入排序

    直接插入排序简介

    直接插入排序(Straight Insertion Sort)的基本思想是:把n个待排序的元素看成一个有序表和一个无序表。开始的时候有序表中只包含1个元素,无序表中只包含n-1个元素,排序的过程每次从无序表中选取第一个元素,将它插在有序表中的适当的位置,构造新的有续表,重复n-1次上述过程,直到排序完成。
    以数组{38,65,97,76,13,27,49}为例,直接插入排序的具体步骤如下:

    第1步插入38之后:[38],65,97,76,13,27,49
    第2步插入38之后:[38,65],97,76,13,27,49
    第3步插入38之后:[38,65,97],76,13,27,49
    第4步插入38之后:[38,65,76,97],13,27,49
    第5步插入38之后:[13,38,65,76,97],27,49
    第6步插入38之后:[13,27,38,65,76,97],49
    第7步插入38之后:[13,27,38,49,65,76,97]

    从上面的排序过程可以看到,我们把数组分成有序区和无序区,我们所做的工作只有两步:

    • 取出无序区中的第一个数,并找出它在有序区当中对应的位置
    • 将无序去的数据插入到有序区,如果有必要就对有序区中的相关数据进行移位操做。

    下面上代码:

    import java.io.*;
    public class InsertSort 
    {
        public static void insertSort(int[] array){
            if (array.length <= 0)
                return;
            
            int i = 0, j = 0, k = 0, n = array.length;
            
            for(i = 1; i < n; i ++){//从1开始是默认数组中第一个元素是有序区中的
                //为array[i]在前面的array[0...i-1]有序区间中找一个合适的位置
                for(j = i-1; j >= 0; j --) {
                    if(array[j] < array[i])
                        break;
                }
                //如找到了一个合适的位置
                if(j != i-1) {
                    //将比a[i]大的数据向后移
                    int tmp = array[i];
                    for(k = i-1; k > j; k--) {
                        array[k+1] = array[k];
                    }
                     //将a[i]放到正确位置上
                    array[k+1] = tmp;
                }
            }
        }
        public static void main (String[] args) { 
            int[] array = {38,65,97,76,13,27,49};
            insertSort(array);
            for(int i: array)
                System.out.println(i);
        }
    }
    

    从上面可以看出我们是先查找位置,然后才进行移位,其实可以稍微的改进一下,边查找边移位,这样虽然没有减少时间复杂度,但是过程看起来更加的简洁:

     public static void insertSortChange(int[] array){
            if (array.length <= 0) {
                return;
            }
            for (int i = 1; i < array.length; i++) {
                int tmp = array[i];
                int j = i;
                if (array[j-1] > tmp) {
                    while (j >= 1 && array[j-1] > tmp ) {
                        array[j] = array[j-1];
                        j--;
                    }
                }
                array[j] = tmp;
            }
        }
    

    直接插入排序的时间复杂度和稳定性

    直接插入排序时间复杂度
    直接插入排序的时间复杂度是O(N2)。
    假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1!因此,直接插入排序的时间复杂度是O(N2)。

    直接插入排序稳定性
    直接插入排序是稳定的算法,它满足稳定算法的定义。
    算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

  • 相关阅读:
    SpringBoot启动流程
    谈谈Java的线程池设计
    ReentrantReadWriteLock及共享锁的实现
    Condition的await()和signal()流程
    AbstractQueuedSynchronizer与ReentrantLock
    线程状态及各状态下与锁和CPU的关系
    Java运算符和表达式
    Java常量与变量
    jtl文件解析(jmeter+jenkins+python实现接口自动化)
    mac 增加/usr/bin目录的操作无权限
  • 原文地址:https://www.cnblogs.com/chailinbo/p/9287831.html
Copyright © 2011-2022 走看看