Python篇——数据结构与算法(第四部分:希尔排序及其讨论、计数排序、桶排序、基数排序)

news2024/11/20 14:20:45

1、希尔排序

  • 希尔排序(shell sort)是一种分组插入排序算法
  • 首先取一个整数d1=n/2,将元素分为d1个组,每组相邻两元素之间距离为d1,在各组内进行直接插入排序
  • 取第二个整数d2=d1/2,重复上述分组排序过程,知道di=1,即所有元素在同一组内进行直接插入排序。
  • 希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序;最后一趟排序使得所有数据有序

 例如:按照距离d1=n/2,将整个列表分为4组(例子中n=9)

(1) 分别为

  • 第一组 5,3,8
  • 第二组 7,1
  • 第三组 4,2
  • 第四组 6,9

(2)  然后在组内进行插入排序

 (3)然后在取整数d2=d1/2

 (4)当d2的时候,将数组分为了两组,间隔为2的是一组,然后组内又进行插入排序

 (5)组内排序之后的结果图:

 (6)d3=d2/2,此时距离d3为1的为一组(当d3=1的时候相当于直接进行插入排序)

 (7)结果如图所示:

 (8)代码

def inseart_search_gap(list, gap):
    '''
    :param list: 列表
    :param gap: 分的组
    :return:
    '''
    for i in range(gap, len(list)):
        temp = list[i]
        j = i - gap
        while j >= 0 and list[j] > temp:
            list[j + gap] = list[j]
            j -= gap
        list[j + gap] = temp


def shell_sort(li):
    '''希尔排序'''
    d = len(li) // 2
    while d >= 1:
        inseart_search_gap(li, d)
        d //= 2

Note:

插入排序其实可以看成距离gap=1的情况

2、希尔排序的讨论

希尔排序的时间复杂度比较复杂,并且与选择的gap序列有关

 3、计数排序

  • 对列表进行排序,已知列表中的数的取值范围都在0到100之间。设计时间复杂度为O(n)的算法

# 计数排序
import random


def count_sort(li, max_count=100):
    '''
    :param li:列表
    :param max_count:列表中最大取值
    '''
    count = [0 for _ in range(max_count + 1)]
    # 表示无论我遍历到第几次,不关心当前值是多少,而是一律输出0,因为取值范围是0-100,所以在生成列表的时候,我们要考虑到101
    for val in li:
        count[val] = count[val] + 1
    # 清空原列表,避免新建列表
    li.clear()
    for index, value in enumerate(count):
        for i in range(value):
            li.append(index)


li = [random.randint(0, 100) for _ in range(1000)]
print(li)
count_sort(li)
print(li)

Note:

  • 缺陷如下:
    • 开辟列表空间浪费资源,比如取值范围是0-100就需要列表长度为100的列表
    • 需要知道给定数据的取值范围

 4、桶排序

  • 在计数排序中,如果元素的范围比较大(比如在1到1亿之间),如何改造算法
  • 桶排序(Bucket Sort):首先将元素分在不同的桶中,在对每个桶中的元素排序

# 桶排序
def bucket_sort(li, n=100, max_number=10000):
    '''
    :param li: 列表
    :param n: 分成多少桶
    :param max_number:最大取值范围
    '''
    buckets = [[] for _ in range(n)]  # 列表生成式(创建桶),例如:[[],[],[],...]
    for var in li:
        # 例如:每个桶放的范围是(max_number//n),假设var是86,那么它应该放在0号桶内,var整除(max_number//n)是0
        # 其中n-1表示最后一个桶,min()函数用于防止桶越界,即使数字为10000,也放入最后一个桶
        i = min(var // (max_number // n), n - 1)  # (表示var放到几号桶内)
        buckets[i].append(var)
        # for 循环结束元素都放入桶中
        for j in range(len(buckets[i]) - 1, 0, -1):  # 对第i号桶进行排序,j表示桶内最后一个元素开始,这里写0是因为前包后不包,范围到1号位置元素
            # [0,2,4,3] 假设放入的元素为3,需要j从最后遍历到2这个元素位置
            if buckets[i][j] < buckets[i][j - 1]:
                # 交换元素
                buckets[i][j], buckets[i][j - 1] = buckets[i][j - 1], buckets[i][j]
            else:
                break
    sort_li = []  # 新建列表
    for buc in buckets:
        sort_li.extend(buc)  # 将一个列表加到另一个列表后面
    return sort_li

Note:

  • 桶排序的表现取决于数据的分布。也就是要对不同数据排序时采用不同的分桶策略
  • 平均情况时间复杂度:O(n+k)
  • 最坏情况时间复杂度:O(n^2*k)
  • 空间复杂度:O(nk)
  • 数据排序部分可以根据实际需要进行优化

5、基数排序

 (1)多关键字排序

  • 假如现在有一个员工表,要求按照薪资排序,年龄相同的员工按照年龄排序
    • 先按照年龄排序,再按照薪资进行稳定排序(稳定:相对位置不变
  • 对32,13,94,52,17,54,93进行排序,是否可以看做多关键字排序

 Note:

  • 先按照个位数分桶

 

  • 然后依次输出

  •  按照十位数分桶

  •  在依次输出

 (2)基数排序的实现

def radix_sort(li):
    max_num = max(li)  # max value 8->1 99->2 888->3 9999->4
    it = 0  # 迭代次数
    while 10 ** it <= max_num:
        buckets = [[] for _ in range(10)]
        for var in li:
            # 找某一位的数 987   it=1 取个位:987%10(取模)  it=2 取十位:987//10=98   98%10=8
            digit = (var // 10 ** it) % 10
            buckets[digit].append(var)
        # 分桶结束
        li.clear()
        for buc in buckets:
            li.extend(buc)
        # 重新写回li
        it += 1


import random

li = list(range(100))
random.shuffle(li)
radix_sort(li)
print(li)

Note:

  • 时间复杂度:O(Kn)
  • 空间复杂度:O(K+n)
  • K表示数字位数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/591186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud Alibaba Seata 工作机制

SpringCloud Alibaba Seata Seata 工作机制 说明 之所以放在后面说工作机制是因为如果一开始就说的话理解困难 所以我们有了前面的列子和说明我们在结合本节内容会收获的多理解相对容易点 分布式事务过程分析 Seata 分布式事务处理过程-ID三组件模型 debug 梳理: 术语 先…

C++ deque类成员函数介绍

目录 &#x1f914;deque模板介绍&#xff1a; &#x1f914;deque特点&#xff1a; &#x1f914;deque内存结构图解&#xff1a; &#x1f914;deque各操作地址指向&#xff1a; &#x1f914; deque的成员函数&#xff1a; deque构造函数&#xff1a; &#x1f50d;代…

C++ 常见集合算法

目录 &#x1f914;常见集合算法&#xff1a; &#x1f642;1.set_intersection 容器交集 代码示例&#xff1a; 运行结果&#xff1a; &#x1f642;2.set_union 容器并集 图解&#xff1a; 代码示例&#xff1a; 运行结果&#xff1a; &#x1f642; 3.set_differe…

高速缓存(cache)的原理: 了解计算机架构与性能优化

计基之存储器层次结构 Author&#xff1a; Once Day Date&#xff1a; 2023年5月9日 长路漫漫&#xff0c;而今才刚刚启程&#xff01; 本内容收集整理于《深入理解计算机系统》一书。 参看文档: 捋一捋Cache - 知乎 (zhihu.com)iCache和dCache一致性 - 知乎 (zhihu.com)C…

【SpringCloud——Elasticsearch(上)】

一、什么是Elasticsearch elasticsearch是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。 二、倒排索引 1、正向索引 2、倒排索引 3、总结 三、ES和MySQL的区别 四、操作索引库 1、基于Kibana&#xff08;WEB界面&#xff09; 以下操作…

jvisualvm ssl远程连接JVM

jvisualvm 远程ssl连接 一、没认证的 JMX连接 (不安全) 这种方式&#xff0c;仅限于测试环境&#xff0c;可以这样操作。生产环境为了安全起见&#xff0c;还是要使用带认证的方式连接。 远程jar包服务 启动时 java -jar [jvm参数] xx.jar添加JVM参数 java -jar -Xmx512M -Xms2…

基于深度学习的高精度汽车自行车检测识别系统(PyTorch+Pyside6+模型)

摘要&#xff1a;基于深度学习的高精度汽车自行车检测识别系统可用于日常生活中检测与定位汽车自行车目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的汽车自行车目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目…

基于深度学习的高精度野生动物检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度野生动物检测&#xff08;水牛、犀牛、斑马和大象&#xff09;识别系统可用于日常生活中或野外来检测与定位野生动物目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的野生动物目标检测识别&#xff0c;另外支持结果可视…

Flutter问题记录 - TextField组件多行提示文本显示不全

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 梳理Flutter项目的过程中发现还有一些遗留的TODO没处理&#xff0c;其中有一个和TextField组件相关。 开发环境 Flutter: 3.10.1Dart: 3.0.1 问题描述 TextField组件设置maxLines: null不限制行数&#xff0c;同时…

【文章学习系列之模型】SCALEFORMER

本章内容 文章概况模型结构主要方法多尺度框架跨尺度标准化模型输入编码损失函数 实验结果消融实验跨尺度标准化自适应损失函数 总结 文章概况 《SCALEFORMER: ITERATIVE MULTI-SCALE REFINING TRANSFORMERS FOR TIME SERIES FORECASTING》是2023年发表于ICLR上的一篇论文。作…

硬件工程师-BUCK开关电源设计

一、电感的伏安特性 电感线圈通电之后&#xff0c;会产生磁场&#xff0c;磁场是有一定极性的&#xff0c;而且磁场分布&#xff0c;是一个封闭的回路。在线圈的内部磁力线是比较密集的&#xff0c;磁场的强度是比较强的&#xff0c;外面空气中的的这个磁力线是比较稀疏的&…

【Unity3D】调整屏幕亮度、饱和度、对比度

1 屏幕后处理流程 调整屏幕亮度、饱和度、对比度&#xff0c;需要使用到屏幕后处理技术。因此&#xff0c;本文将先介绍屏幕后处理流程&#xff0c;再介绍调整屏幕亮度、饱和度、对比度的实现。 屏幕后处理即&#xff1a;渲染完所有对象后&#xff0c;得到一张屏幕图像&#xf…

Centos6.5环境Nginx 1.16.1升级到1.24.0版本

一、背景 2023年4月11日&#xff0c;官方发布了Nginx最新稳定版&#xff0c;版本号为 1.24.0。该版本是基于1.23.x&#xff08;1.23.0 - 1.23.4&#xff09;开发版的Bug修复&#xff0c;以及一些新特性的加入&#xff0c;而形成的稳定版。安全部门扫描后&#xff0c;发现现场不…

车载ECU休眠唤醒-TJA1145

前言 首先&#xff0c;请教大家几个小小问题&#xff0c;你清楚&#xff1a; 什么是TJA1145吗&#xff1f;你知道休眠唤醒控制基本逻辑是怎么样的吗&#xff1f;TJA1145又是如何控制ECU进行休眠唤醒的呢&#xff1f;使用TJA1145时有哪些注意事项呢&#xff1f; 今天&#xff…

chatgpt赋能python:Python中如何输入中文——从安装到常见问题解决

Python中如何输入中文——从安装到常见问题解决 Python是一门广泛使用的编程语言&#xff0c;其优秀的开源性、易用性、灵活性以及庞大的生态圈也令越来越多的人选择Python。但是对于初学者来说&#xff0c;如何正确输入中文常常成为一个问题。本篇文章从安装、常见问题解决、…

LeetCode 560 和为 K 的子数组

LeetCode 560 和为 K 的子数组 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/subarray-sum-equals-k/description 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 给你一个整数数组 …

ChatGPT的4个不为人知却非常实用的小功能

今天重点介绍四个ChatGPT很实用的小功能。 一、停止生成 如果在ChatGPT输出内容的过程中&#xff0c;我们发现结果不是自己想要的&#xff0c;可以直接点击“Stop generating”按钮&#xff0c;这样它就会立即停止输出。 二、复制功能 在ChatGPT返回对话的右侧&#xff0c;有三…

在vue中集成高德地图amap-jsapi-loader

前往高德地图开发平台高德开放平台 | 高德地图API 一&#xff1a;申请高德key 去高德官网去创建一个属于自己的地图应用 &#xff08;得到key和秘钥&#xff09; 。 首先&#xff0c;我们要注册一个开发者账号&#xff0c;根据实际情况填写&#xff0c;身份写个人&#xff1a;…

制作嵌入式busybox rootfs系统

1、busybox下载 BusyBox 此篇使用版本BusyBox 1.31.1 (stable) 2、设置交叉编译环境变量 source environment-setup-aarch64-poky-linux或者其他架构的编译链工具 3、busybox编译设置 cd busybox-1.31.1 修改根目录Makefile中的CROSS_COMPILE和ARCH参数 比如ARCH ? ar…

Flask-RESTful的使用

Flask-RESTful的使用 Flask-RESTful基本使用安装定义资源Resources创建API实例添加资源到API运行Flask应用 请求处理请求解析参数校验 响应处理数据序列化定制返回格式 其他功能蓝图装饰器集合路由命名规范路由名称 Flask-RESTful Flask-RESTful是一个用于构建RESTful API的扩展…