• 数据结构之内部排序--折半插入排序


    概要

    -IDE:Pycharm
    -Python版本:python3.x
    -算法分类:内部排序->插入类排序->折半插入排序

    算法思想

    对于有序表进行折半查找,其性能优于顺序查找。所以,可以将折半查找的思想用于在
    有序记录$r[1,2,3,...,i-1]$中确定插入位置,相应的排序算法称为折半插入排序。
    例如:序列$r$长度为$n$,前i项有序,待排的记录为$r[i+1]$。此时低位为$r[1]$,高位为$r[i-1]$,
    查找$r[j]$,$ j=(i+1)/2$。 若$r[j]>r[i+1]$,此时证明那个,待排记录,在$1-j$之间的位置。高位变为$r[j-1]$,若小于则相反,以此类推,找到合适的位置。
    最后则是将记录向后移一位。将待插入的值放入合适的位置。

    算法分析

    采用折半插入排序,可以减少关键字的比较次数。每插入一次元素,需要比较的次数最大是折半判定树的深度。如插入第$i$个元素时设$i=2j$,则需要进行$log2i$次比较,因此插入$n-1$个元素平均关键字比较次数$nlog2n$。折半插入改变了元素的比较次数,但是没有改变元素的移动耗费时间。所以其时间复杂度仍为$O(n2)$。

    稳定性与时间复杂度

    排序算法 稳定性 时间复杂度 最好情况 最坏情况 空间复杂度
    折半插入 稳定 $O(n^2)$ $O(nlogn)$ $O(n^2)$ $O(1)$

    Python代码清单

    # !/usr/bin/python3
    #  _*_ coding:utf-8 _*_
    #  折半插入排序
     
    import sys  # 导入sys,使用argv接收外部参数。
    import time  # 导入time 用time() 进行记时。
    import random  # 导入随机数包生存随机数
     
     
    def BIS(number,maxNumber):  # 算法,number是传入生成的个数,maxNumber代表生成的最大数
     
        # 生成随机数
        timeStart = time.time()
        listA = [0]  # 设置第一个值,防止 out of index ,设置变量
        for i in range(number):
            listA.append(random.randint(0, maxNumber))  # 添加生成的值。
     
        timeEnd = time.time()
        timeIs = timeEnd-timeStart
        print('生成%d个数的时间是%f' % (number, timeIs))
      #  print(listA)
        ####################################################
     
        # 进行排序
        timeStart = time.time()
        for aim in range(2, number+1):  # 选定范围
            low = 1  # 设置低位
            high = aim-1  # 设置高位为对象减1
            listA[0] = listA[aim]  # 设置对象
     
            while(low <= high):  # 判断高位与低位是否相交,若相交则说明找到位置。
                mid = int((low+high)/2)  # 折半取中间值
                if((listA[mid]) > listA[0]):  # 判断取右方值还是左方值。
                    high = mid - 1  # 取左方 高位为mid-1
                else:
                    low = mid + 1  # 取右方 低位为mid +1
     
            for count in range(0, aim-low):  # aim-low 是循环的次数
                listA[aim] = listA[aim-1]  # 这里是从后向前移
                aim = aim - 1  # 向前加一
            listA[low] = listA[0]  # 最后替换值
     
        timeEnd = time.time()
        timeIs = timeEnd-timeStart
        print('排序%d个数的时间是%f' % (number, timeIs))
       # print(listA)
     
     
    if __name__ == '__main__':
     
        helpInfo = '''
            This program is for Binary Insertion Sort.
            How to use it! Follow the example!
     
            python Binary_Insertion_Sort.py 10 100
     
            The 10 representative will generate ten numbers.
            100 representative the max-number you make.
     
        '''
     
        command = sys.argv[0:]  # 从键盘获取输入信息。
        lenght = len(command)  # 计算信息长度
     
        if lenght != 3 or 'help' in command:  # 第一判断,对长度是否合法与是否有帮助文字进行判断。
            print(helpInfo)
        else:
            try:
                number = int(command[1])  # 第二次判断,对输入数据进行int转化,即判断是否为int
                maxNumber = int(command[2])
            except ValueError:
                print(helpInfo)
                sys.exit(1)  # 若不是int,则退出程序
            BIS(number, maxNumber)  # 调用方法,生成序列并排序。
    
    

    有什么问题请联系我

    QQ:3116316431 (请附上信息)
    E-mail:wongyinlong@yeah.net

  • 相关阅读:
    BUG记录之 Database Connection Can’t Be Open!
    C#基础拾遗03注册表保存用户设置
    JQuery Ajax小磨合1
    SQL Server几个常用Date函数(二)
    浅谈设计模式01策略模式
    C#基础拾遗02XML串行化
    SQL Server 2008 R2学习心得
    WebService重载问题
    SQL Server几个常用date函数(一)
    C#获取打印机列表
  • 原文地址:https://www.cnblogs.com/Leon-The-Professional/p/9950089.html
Copyright © 2020-2023  润新知