排序算法(系列)

ops/2024/12/26 11:15:15/

希尔排序(Shell Sort)是一种插入排序的改进版本。它是基于插入排序的思想,通过将待排序的元素进行分组,然后对每组进行插入排序,逐步减少分组的大小,最终完成排序。希尔排序的核心思想是将序列分为多个子序列,对每个子序列进行插入排序,然后逐步缩小子序列的长度,直到最后一次对整个序列进行插入排序。

计数排序(Counting Sort)是一种非比较算法>排序算法,它通过确定每个元素在数组中的位置来完成排序。计数排序的核心思想是统计每个元素的出现次数,并根据出现次数确定元素在排序后的最终位置。计数排序适用于待排序元素为确定范围的整数的情况。

桶排序(Bucket Sort)是一种算法>排序算法,它将待排序的元素划分为多个桶,每个桶中存放一定范围内的元素。然后对每个桶中的元素进行排序,最后将所有桶中的元素按桶的顺序依次取出,即得到排好序的序列。桶排序适用于待排序元素分布均匀的情况。

基数排序(Radix Sort)是一种多关键字算法>排序算法,它将待排序元素按照关键字的各个位进行排序。基数排序从最低位开始,对每个关键字进行排序,直到最高位。基数排序可以用于对十进制、二进制等各种进制的数进行排序。基数排序的核心思想是按照关键字的各个位进行分配和收集,通过多次分配和收集来完成排序。

这四种算法>排序算法都有各自的特点和适用范围,可以根据具体问题的要求选择合适的算法>排序算法

目录

希尔排序

计数排序O(n)

桶排序

基数排序

基数排序

基数排序的实现


希尔排序

基于插入排序(摸牌)(把插入排序中的1换成了gap)

python"># 希尔排序
def insert_search_gap(li,gap):for i in range(gap,len(li)):      # i 表示趟数,也表示未排序的数的下标temp = li[i]        # 用于存储将要排序的数j = i-gap     # 表示已排序好的数下标while j >= 0 and li[j] > temp:          # 找出能够插入的位置li[j+gap] = li[j]         # 向右移动 空出位置放置li[i]j -= gap              # 下标向前指 继续比较li[j+gap] = temp
​
def shell_sort(li):d = len(li)//2while d > 0:insert_search_gap(li,d)d //= 2
​
​
li = list(range(100))
import random
random.shuffle(li)
print(li)
shell_sort(li)
print(li)

计数排序O(n)

python"># 计数排序
def count_sort(li,max_count=100):     #max_count = 100默认最大的数是100count = [0 for _ in range(max_count+1)]for val in li:count[val] += 1li.clear()for ind,val in enumerate(count):       # ind列表下标 val下标次数for j in range(val):li.append(ind)
​
import random
li = [random.randint(0,100)for _ in range(1000)]
print(li)
count_sort(li)
print(li)

桶排序

时间复杂度较难讨论

适用于分布均匀且数额较大。

python"># 桶排序  不重要
def bucket_sort(li,n = 100,max_num = 10000):bucket = [[] for _ in range(n)]     # 创建桶for var in li:i = min(var //(max_num // n), n-1)      # i 表示var放到几号桶 若100桶,但是没有这时候就放在n-1 = 99bucket[i].append(var)# 保持桶里边的顺序for j in range(len(bucket[i])-1,0,-1):if bucket[i][j] < bucket[i][j-1]:bucket[i][j],bucket[i][j-1] = bucket[i][j-1], bucket[i][j]else:breaksorted_li = []for buc in bucket:sorted_li.extend(buc)return sorted_li
​
import random
​
li = [random.randint(0,100)for i in range(10000)]
# print(li)
li = bucket_sort(li)
print(li)

基数排序(O(kn))

基数排序

先按照个位进行桶排序(按照个位进桶再依次出来),再按照十位进行桶排序(一样)

基数排序的实现

python"># 基数排序的实现
# 时间复杂度O(kn)(k表示数字位数)
def radix_sort(li):max_num = max(li)      # 最大值9—>1次分桶,99->2,888->3,10000->5it = 0while 10 ** it <= max_num:buckets = [[] for _ in range(10)]# 分桶for var in li:# 取个位it=0,987%10=7# 取十位987 it=1  987//10->98 98%10=8# 取百位987 it=2   987//10^it=9 9%10=9digit = (var//10**it) % 10buckets[digit].append(var)li.clear()for buc in buckets:li.extend(buc)it += 1import random
li = list(range(1000))
random.shuffle(li)
radix_sort(li)
print(li)


http://www.ppmy.cn/ops/145112.html

相关文章

赛博错题本

机构抽象老师非得让我们整一个错题本&#xff0c;我寻思都学计算机了&#xff0c;还在整高中做题呢一套是什么意思呢&#xff0c;更何况考试也就一周一次&#xff0c;你整个本完完全全没有必要&#xff0c;整个赛博错题本得了。以后错题都会存在这里&#xff0c;基本上一周一更…

C#中的属性索引器(Indexer)

属性索引器&#xff08;Indexer&#xff09;是C#中一个非常有用的特性&#xff0c;它允许类的实例像数组一样通过索引进行访问。索引器不仅限于整数索引&#xff0c;还可以使用其他类型&#xff0c;如字符串&#xff0c;作为索引键。这使得索引器在访问集合类型或需要通过键来访…

[源码解析] 模型并行分布式训练Megatron (2) --- 整体架构

link [源码解析] 模型并行分布式训练Megatron (2) --- 整体架构 目录 [源码解析] 模型并行分布式训练Megatron (2) --- 整体架构 0x00 摘要0x01 启动 1.1 分布式启动1.2 构造基础 1.2.1 获取模型1.2.2 获取数据集1.2.3 步进函数 1.2.3.1 广播数据0x02 Pretrain0x03 初始化 3.1 …

Go语言中context 结构原理, 使用场景和用途

Go语言中context结构原理 在Go语言中&#xff0c;context是一个用于在API边界之间传递请求范围的值、取消信号、截止时间等信息的机制。它主要用于处理跨API边界的请求取消、超时控制以及传递请求范围内的共享数据。context的设计目标是为了解决在并发编程中&#xff0c;特别是…

SAM大模型实践(六)

今天试了一下geo-SAM快速版本fast-sam&#xff0c;项目参考地址如下&#xff1a; https://samgeo.gishub.org/examples/fast_sam/https://samgeo.gishub.org/examples/fast_sam/具体代码如下&#xff1a; # %pip install segment-geospatial segment-anything-fast # 在conda…

【Java基础面试题025】什么是Java的Integer缓存池?

回答重点 Java的Integer缓存池&#xff08;Integer Cache&#xff09;是为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围&#xff0c;因此缓存这些对象可以减少内存分配和垃圾回收的负担&#xff0c;提升性能 在 -128到127范围内的Integer对象会…

常见网络攻击场景常被用于测试系统安全性

常见网络攻击场景常被用于测试系统安全性 在区块链系统中,以下网络攻击场景常被用于测试系统安全性: 51% 攻击 攻击原理:当一个或一组攻击者控制了超过全网 50%的算力时,就有可能操纵区块链的账本记录。在工作量证明(PoW)机制下,攻击者可以通过算力优势,实现对新区块的…

聊一聊 C#线程池 的线程动态注入

一&#xff1a;背景 1. 讲故事 上一篇我们用 Thread.Sleep 的方式演示了线程池饥饿场景下的动态线程注入&#xff0c;可以观察到大概 1s 产生 1~2 个新线程&#xff0c;很显然这样的增长速度扛不住上游请求对线程池的DDOS攻击&#xff0c;导致线程池队列越来越大&#xff0c;但…