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

                    直接插入排序

                                          作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

    一.直接插入排序(Direct insertion sort)概述

    在为排序序列中,构建一个子排序序列,直至全部数据排序完成
    
    将代排序的数,插入到已经排序的序列中合适的位置
    
    增加一个哨兵,放入比较值,让它和后面已经排好的序列比较,找到合适的插入点

    二.直接插入排序原理

    初始值:[1 9 8 5 6]
    
    第一趟:[0 1 9 8 5 6] [9 1 9 8 5 6]  -> [1 9 8 5 6]                    #如大家所看到的,和初始值必须,我在第一个位置上增加了一个数字0,这个数字0的位置我们称其为哨兵,接下来我们直接取初始值的第二个索引9和它前面一个索引比较(第一个索引相比较),哨兵9比1大,则不需要交换位置,本轮比较结束。

    第二趟:[8 1 9 8 5 6] [8 1 ? 9 5 6] [8 1 8 9 5 6] -> [1 8 9 5 6]           #拿到上一轮比赛结果,接下来我们直接取初始值的第三个索引8和它前面一个索引比较,本轮哨兵为8,而哨兵8比9小,因此,我们需要把9往右移动一位,此时哨兵被插入8和9交换位置索引变为第二个索引,此时依旧需要和前面的一个索引进行比较,很显然第一个索引为1,而哨兵为8,哨兵8比1大,则不需要交换位置,本轮比赛结束。(简单的说就是如果比本轮哨兵大就相互交换位置,如果比本轮哨兵小则本轮结束)

    第三趟:[5 1 8 9 5 6] [5 1 8 ? 9 6] [5 1 ? 8 9 6] [5 1 5 8 9 6] -> [1 5 8 9 6]   #拿到上一轮比赛结果,接下来我们直接去初始值的第四个索引5和它前面一个索引比较,本轮哨兵为5,而哨兵5比9小,因此他们需要相互交换位置,接着哨兵5再和它前面一个索引比较,哨兵5比8小,继续交换位置,然后继续和它前面一个索引比价,发现哨兵5比1大,终止本轮比赛。

    第四趟:[6 1 5 8 9 6] [6 1 5 8 ? 9] [6 1 5 ? 8 9] [6 1 5 6 8 9] -> [1 5 6 8 9] #拿到上一轮的结果,继续重复插入排序比较,经过上面3次比较,想必大家也清楚它是如何排序的了,最终经过四趟比较,得到的排序是:1 5 6 8 9

    三.使用Python代码实现直接插入排序

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 
     7 """
     8 思路:
     9     增加一个哨兵位,每轮比较将比较数放入
    10     哨兵依次和前一个数据比较,大数靠右移动,找到哨兵中值的插入位置
    11     每一轮结束后,得到一个从开始到待比较数位置的一个有序序列
    12 
    13 插入排序特点:
    14     最好情况,正好是升序排列,比较迭代n-1次
    15     最差情况,正好是降序排列,比较迭代1,2,...,n-1即 n(n-1)/2
    16     使用两次嵌套循环,时间复杂度O(n^2)
    17     稳定排序算法
    18     使用在小规模数据比较
    19     待优化:
    20         如果比较操作耗时大的话,可以采用二分查找提高效率,即二分查找插入排序
    21 
    22 """
    23 
    24 m_list = [
    25     [1,9,8,5,6,7,4,3,2],
    26     [1,2,3,4,5,6,7,7,9],
    27     [9,8,7,6,5,4,3,2,1],
    28     [1,1,1,1,1,1,1,1,2]
    29 ]
    30 
    31 nums = [0] + m_list[2]
    32 print(m_list[2])
    33 
    34 sentinel,*origin = nums     #哨兵位,待比较数字
    35 
    36 count_swap = 0
    37 
    38 count_iter = 0
    39 
    40 length = len(nums)
    41 
    42 for i in range(2,length):   #从2开始
    43     nums[0] = nums[i]       #放置哨兵
    44     j = i - 1
    45     count_iter += 1
    46     if nums[j] > nums[0]:   #大数右移,找到插入位置
    47         while nums[j] > nums[0]:
    48             nums[j +1] = nums[j]    #依次右移
    49             j -= 1
    50             count_swap += 1
    51         nums[j + 1] = nums[0]       #将哨兵插入,注意插入在右侧要+1
    52 
    53 print(nums,count_swap,count_iter)
    54 
    55 
    56 
    57 #以上代码执行结果如下:
    58 [9, 8, 7, 6, 5, 4, 3, 2, 1]
    59 [1, 1, 2, 3, 4, 5, 6, 7, 8, 9] 36 8
  • 相关阅读:
    Jmeter运行badboy录制的脚本
    Bugfree安装与使用
    JMeter录制脚本
    第六天-linux系统优化初步讲解
    第五天-linux基础命令
    第四天-secureCRT-ssh客户端使用详解
    第三天-linux版本选择及安装
    第二天-计算机硬件基本知识和linux发展简史
    第一天-学习linux运维
    ubuntu15.04 无线上网问题
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/10959123.html
Copyright © 2011-2022 走看看