zoukankan      html  css  js  c++  java
  • [算法] 插入排序 Insertion Sort

    插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

    一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

    1. 从第一个元素开始,该元素可以认为已经被排序
    2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
    3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
    5. 将新元素插入到该位置后
    6. 重复步骤2~5

    如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找插入排序。

    从数据第二个元素开始遍历
    0    1    2    3    4    5    
    
    20     40    30    10    60    50
    20     40    30    10    60    50
    20     30    40    10    60    50
    10     20    30    40    60    50
    10     20    30    40    50    60
    
    
    i=1;     temp=a[1]=40;     j=i-1=0; a[0]>40,若前面的元素比当前元素大。
    
    i=2;     temp=a[2]=30,    j=i-1=1;a[1]>30   成立,a[2]=a[1], 让a[1]往后移动一位.j- - 继续前移,再比较,j=0,a[0]>30,否,退出循环。a[1]=30. 
    
    I=3;  temp=a[3]==10, j=i-1=2; a[2]>10 ? 成立,a[3]=a[2],让a[2]往后移动一位到a[3]的位置.
    j- -  ; j = 1 ; a[1]>10 ? 成立,a[2]=a[1],让a[1] 往后移动一位到a[2]的位置。
    j- - ; j=0 ; a[0]>10? 成立,a[1]=a[0],让a[0]往后移动一位到a[1]的位置。
    j- - ;j=-1; 跳出循环,a[-1+1] =a[0] = 10 ;插入当前值。
    
    I=4,temp=a[4]=60,j=i-1=3,a[3]>a[4]? 不成立,跳出循环 
    a[j+1] =a[i] =60
    
    i=5,temp=a[5]=50, j=i-1=4,判断a[4]>50 ,成立,a[5]=a[4] 
    j- - ; j =3 ; a[3]>50成立? 不成立,跳出循环。
    J[4]= 50 ;插入当前值。

    使用插入排序为一列数字进行排序的过程

    Java代码示例:

    package com.sort;
    
    
    public class InsertSort {
    
        /*
         * 直接插入排序
         * 
         * 参数说明: a -- 待排序的数组 n -- 数组的长度
         */
        public static void insertSort(int[] a, int n) {
            int length = a.length; // 数组长度
            int i; // 当前值的位置
            int j; // 指向j前的位置
            int temp; // 当前要进行插入排序的值
            // 从数组的第二个位置开始遍历值
            for (i = 1; i < length; i++) {
                temp = a[i];
                j = i - 1;
                // a[j]比当前值大时,a[j]后移一位,空出j的位置,好让下一次循环的值后移
                while (j >= 0 && a[j] > temp) {
                    a[j + 1] = a[j]; // 将a[j]值后移
                    j--; // j前移 
                }
                // 跳出循环(找到要插入的中间位置或已遍历到0下标)
    
                a[j + 1] = temp; // 将当前值插入
    
            }
        }
    
        public static void main(String[] args) {
            int i;
            int[] a = { 20, 40, 30, 10, 60, 50 };
    
            System.out.printf("before sort:");
            for (i = 0; i < a.length; i++)
                System.out.printf("%d ", a[i]);
            System.out.printf("
    ");
    
            insertSort(a, a.length);
    
            System.out.printf("after  sort:");
            for (i = 0; i < a.length; i++)
                System.out.printf("%d ", a[i]);
            System.out.printf("
    ");
        }
    }
    谨言慎行,专注思考 , 工作与生活同乐
  • 相关阅读:
    windows下 php5.3如何连接mssql
    ie 兼容性
    windows 版Tomcat 7.0的配置
    数据库备份
    PHP实现通过经纬度计算距离
    linux内核升级(ubuntu12.04从3.13.0升级到3.4.0 )
    详解Linux Initrd
    基于stm32的can总线彻底研究
    CAN控制器-配置过滤器
    recv send 阻塞和非阻塞
  • 原文地址:https://www.cnblogs.com/tmeily/p/4250275.html
Copyright © 2011-2022 走看看