zoukankan      html  css  js  c++  java
  • 算法学习-02(希尔排序,计数排序,桶排序,基数排序)

    希尔排序

    # 希尔排序
    # 希尔排序是对插入排序的升级改造
    # 它的大致流程是
    # 1、将长度为n的序列 分为d = n//2组
    # 2、使每一组变的有序
    # 3、将序列分为 d1 = d // 2 组
    # 4、将每一组变的有序
    # 5、直到最后 d 小于等于 0
    
    def inster_sort_gap(li,gap):
        for i in range(gap,len(li)):
            tmp = li[i]
            j = i - gap
            while j >= 0 and tmp > li[j]:
                li[j+gap] = li[j]
                j -= gap
            li[j+gap] = tmp
    
    def shell_sort(li):
        n = len(li)
        gap = n // 2
        while gap > 0:
            inster_sort_gap(li,gap)
            gap //= 2

    计数排序

    #计数排序
        对列表进行排序,已知列表中的数范围都在0到100之间。
        设计时间复杂度为O(n)的算法
    #eg:
        1 3 2 4 1 2 3 1 3 5
    # 分配0-5六个桶,遇到一个数,在相应的桶上加一
    0
    1 1+1+1
    2 1+1
    3 1+1+1
    4 1
    5 1
    
    复杂度 O(n)
    占用空间 O(n)
    
    # 计数排序
    def count_sort(li, max_count):
        count = [0 for _ in range(max_count+1)]
        for i in li:
            count[i] += 1
        li.clear()
        for ind, val in enumerate(li):
            for i in range(val):
          li.append(ind)

    桶排序

    # 如果计数排序中,如果元素的范围比较大(比如在1到1亿之间),如何改造算法
    
    # 桶排序(Bucket Sort):
        把元素放在不同的桶里,对每个桶里面的元素保持有序
    
    def bucket_sort(li,n=100,max_num=10000):
        """
        :param li: 需要排序的列表
        :param n: 分多少个桶
        :param max_num: 最大数
        :return:
        """
        buckets = [[] for _ in range(n)]
        for var in li:
            i = min(var // (max_num // n), n-1)  # i 表示var放到几号桶里面
            buckets[i].append(var)  # 把var 放到对应的桶里
            # 保持桶内的顺序
            for j in range(len(buckets[i])-1, 0, -1):
                if buckets[i][j] < buckets[i][j-1]:
                    buckets[i][j], buckets[i][j-1] = buckets[i][j-1], buckets[i][j]
                else:
                    break
        sorted_li = []
        for buc in buckets:
            sorted_li.extend(buc)
        return sorted_li
    # 范围特别大,用的不是太多 # 桶排序的效率 # 取决于数据的分布,也就是需要对不同数据排序时,采取不同的分桶策略 # 平均分布--- # 不平均,90%的数在某一个桶里 # # 平均情况时间复杂度:O(n+k) # 最坏情况时间复杂度:O(n**2k) # 空间复杂度:O(nk) # 还可以优化,比如内部排序过程

    基数排序

    # 先行知识点: 基于多关键字排序
        eg:对员工表进行薪资排序,薪资相同的按照年龄排序
              先按照年龄进行排序,再按照薪资进行稳定的排序
    
    #对 32,13,19,52,54,94,3,17 的排序,也可以看作是多关键字排序
    #先对个位数进行桶排序,再对十位数进行桶排序
    
    时间复杂度,O(kn)
    空间复杂度,O(k+n)
    k表示数字位数
    
    快排 nlogn  # logn=log(2,n)
    计数排序 kn  # k=log(10,n)
    
    当长度是固定的,数值范围越来越大,达到一定程度100000000...,基数排序的性能会变差
    
    缺陷在于,需要占用空间
    
    字符串的排序
    # abcd
    # ab00  #在面加0
    
    数字排序,是在前面001 ,012,123
    
    小数?
    
    # 基数排序
    def radix_sort(li):
        max_num = max(li)  # 取出最大值,99->2, 888->3, 10000->5
        it = 0  # 7--> it=0  77-->it=2, it等于0的时候,取个位数,it=1的时候,取的是十位数
        while 10 ** it <= max_num:          # 在每次里面进行分桶
            buckets = [[] for _ in range(10)]  # 0-9 共计 10个 桶
            for var in li:
                # 分到几号桶,看的是哪一位的数
                # 怎么取出对应位置上的数字
                # 987 it=0 取第一位7 987%10=7
                #     it=1 取第二位8 987//10=98 98%10=8
                #     it=2 取第三位9 987//100=9 9%10=9
                # 所以,公式: (987//10**it) % 10
                digit = (var // 10 ** it) % 10
                buckets[digit].append(var)
            # 已经做好了分桶
            # 把数重新写进li
            li.clear()
            for buc in buckets:
                li.extend(buc)
            it += 1
  • 相关阅读:
    Mac 下安装Ant
    MAMP 10.10下启动报错解决方案
    [转]常用iOS图片处理方法
    Mac下Android SDK更新不了的解决办法
    细说23+1种设计模式
    mysql应该了解的知识点
    java快排思想
    简介一下 i++和++i&&i=i+i,i+=1;的区别
    对int类型的数据,如何让获取长度
    第一次写博客
  • 原文地址:https://www.cnblogs.com/yxiaodao/p/11933531.html
Copyright © 2011-2022 走看看