尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
1-17-桶排序-BucketSort
桶排序 (Bucket Sort)分桶各自排序摘要本文从浮点数如何线性时间排序的问题出发详解桶排序如何通过分而治之的思路——将元素按值分配到多个桶中每个桶内部独立排序最后按桶顺序合并——实现平均 O(n) 的线性时间复杂度。给出了支持升序/降序的 Python 完整实现标准版、归并版、浮点数版图解了五步核心流程与桶映射公式分析了桶数量、数据分布对性能的影响以及最坏情况退化为 O(n²) 的原因。最后结合 Top K 问题、外部排序等工程场景讨论其设计哲学与面试高频考点。本文属于专栏《算法》系列 1 第 17 篇 | 上一篇计数排序 (Counting Sort) | 下一篇1-18-基数排序-RadixSort文章目录桶排序 (Bucket Sort)分桶各自排序一、问题引入桶排序的核心直觉为什么桶排序能排浮点数二、算法原理图解核心思想桶的映射公式五步流程文字图解桶数量的选择最坏情况数据集中在一个桶三、代码实现标准版桶内插入排序六个关键设计解析归并版桶内用归并排序浮点数专用版运行验证四、复杂度分析时间复杂度空间复杂度稳定性桶排序 vs 计数排序 vs 基数排序五、横向对比性能对比验证最坏情况对比选型建议六、工程实战场景一Top K 高频元素场景二外部排序海量数据排序场景三Pigeonhole Sort鸽巢排序七、常见误区与面试题高频面试题常见实现错误八、总结核心要点适用边界与限制设计哲学一、问题引入上一篇我们讨论了计数排序——一种利用取值范围有限特性的非比较排序时间复杂度 O(n k)。但计数排序有一个明显的局限它只能排整数或可以离散化的数据。如果要排序的数据是浮点数呢比如 10000 个均匀分布在 [0, 1) 区间的浮点数能不能也做到线性时间答案是可以用桶排序。桶排序的核心直觉想象一下图书馆的图书分类图书馆有很多书架桶每本书按类别放到对应的书架上分配每个书架内部再按书名排序桶内排序最后按书架顺序依次浏览所有书就是有序的合并桶排序的思路完全一样先粗分再细排。先把元素按大小范围分到不同的桶里保证前一个桶的所有元素都小于后一个桶的所有元素。然后每个桶内部各自排序最后按桶的顺序依次取出所有元素整体就是有序的。为什么桶排序能排浮点数计数排序之所以不能直接排浮点数是因为计数需要每个值都能作为数组索引——浮点数做不到。但桶排序不需要知道每个具体值只需要知道它属于哪个区间。区间是有限的桶的数量所以浮点数也能排。算法数据类型核心操作时间复杂度计数排序整数、范围小统计每个值的次数O(n k)桶排序数值、分布均匀按区间分桶 桶内排序平均 O(n)基数排序整数、字符串按位排序基于计数排序O(d·n)问题定义输入含 n 个数值的数组arr输出按升序或降序排列的数组核心假设数据分布相对均匀否则性能退化核心操作创建桶 → 分配元素 → 桶内排序 → 合并结果二、算法原理图解核心思想桶排序Bucket Sort的核心是分治思想将大问题分解为多个小问题各自解决后再合并。算法分为五步确定范围找出数据的最小值和最大值创建桶创建 k 个空桶k 为桶的数量分配元素将每个元素按映射规则放入对应的桶桶内排序每个桶内部独立排序合并结果按桶的顺序依次取出元素桶的映射公式如何确定一个元素应该放到哪个桶里最常用的映射方式是线性映射bucket_idx int((val - min_val) / (max_val - min_val) * (bucket_count - 1))这个公式的含义(val - min_val) / (max_val - min_val)将值归一化到 [0, 1] 区间乘以(bucket_count - 1)将 [0, 1] 映射到 [0, bucket_count-1]int()取整得到桶的索引这样保证了最小值 min_val → 第 0 个桶最大值 max_val → 最后一个桶中间值均匀分布在各个桶中五步流程文字图解以数组[0.42, 0.32, 0.33, 0.52, 0.37, 0.47, 0.51]5 个桶为例第一步确定数据范围原数组: [0.42, 0.32, 0.33, 0.52, 0.37, 0.47, 0.51] min_val 0.32 max_val 0.52 val_range 0.20第二步创建桶创建 5 个空桶 桶0: [] 桶1: [] 桶2: [] 桶3: [] 桶4: []第三步分配元素到桶中映射公式: bucket_idx int((val - 0.32) / 0.20 * 4) 0.42 → (0.42-0.32)/0.20*4 0.10/0.20*4 2.0 → 桶2 0.32 → (0.32-0.32)/0.20*4 0.00*4 0.0 → 桶0 0.33 → (0.33-0.32)/0.20*4 0.01/0.20*4 0.2 → 桶0 0.52 → (0.52-0.32)/0.20*4 0.20/0.20*4 4.0 → 桶4 0.37 → (0.37-0.32)/0.20*4 0.05/0.20*4 1.0 → 桶1 0.47 → (0.47-0.32)/0.20*4 0.15/0.20*4 3.0 → 桶3 0.51 → (0.51-0.32)/0.20*4 0.19/0.20*4 3.8 → 桶3 分配结果 桶0: [0.32, 0.33] 桶1: [0.37] 桶2: [0.42] 桶3: [0.47, 0.51] 桶4: [0.52]第四步每个桶内部排序桶0排序: [0.32, 0.33] → 已经有序 桶1排序: [0.37] → 单元素 桶2排序: [0.42] → 单元素 桶3排序: [0.47, 0.51] → 已经有序 桶4排序: [0.52] → 单元素这个例子中数据分布很均匀每个桶的元素都很少桶内排序几乎不花时间第五步按桶的顺序合并桶0 → [0.32, 0.33] 桶1 → [0.37] 桶2 → [0.42] 桶3 → [0.47, 0.51] 桶4 → [0.52] 合并结果: [0.32, 0.33, 0.37, 0.42, 0.47, 0.51, 0.52] ✓桶数量的选择桶的数量 k 是一个重要参数直接影响性能桶数量效果适用场景k n每个元素一个桶退化为计数排序O(n)数据是整数且范围小k √n平衡桶数量和桶内排序开销通用场景k 常数如 10桶内元素多排序开销大数据量小k 1所有元素一个桶退化为桶内排序O(n²)最坏情况桶数量的选择是一个权衡桶太多每个桶元素很少桶内排序很快但桶的管理开销大桶太少桶的管理开销小但每个桶元素多桶内排序慢对于均匀分布的数据理论上当 k n 时每个桶平均 1 个元素桶内排序 O(1)总时间 O(n)。但实际中 k 通常取 √n 或 n/10 等平衡两者开销。最坏情况数据集中在一个桶桶排序的最坏情况是所有元素集中在一个桶里。这时桶排序退化为桶内的那个排序算法数据: [1, 2, 3, 4, 5, ..., 1000]范围0~100000但数据集中在小范围 桶数量: 100 分配结果: 桶0: [1, 2, 3, ..., 1000] ← 所有元素都在这一个桶里 桶1: [] 桶2: [] ... 桶99: [] 桶0内部排序: O(n²) 插入排序 → 退化为 O(n²)这就是桶排序最坏情况 O(n²) 的来源。所以桶排序的性能高度依赖数据分布——数据越均匀桶排序越快数据越集中桶排序越慢。三、代码实现完整代码通过网盘分享的文件算法链接: https://pan.baidu.com/s/1DTJt1X2Is_IQeH5fAXvtZg?pwdyyqf 提取码: yyqf–来自百度网盘超级会员v4的分享标准版桶内插入排序defbucket_sort(arr,ascendingTrue,bucket_count10): 桶排序将元素分配到多个桶中每个桶内部排序再按顺序合并。 核心思想 1. 确定数据范围创建固定数量的桶 2. 将每个元素按映射规则放入对应的桶 3. 每个桶内部排序用插入排序或其他排序算法 4. 按桶的顺序将元素依次取出得到有序数组 时间复杂度平均 O(n k) 最坏 O(n²) | 空间复杂度O(n k) | 稳定排序 其中 k 为桶的数量稳定性取决于桶内排序算法是否稳定。 nlen(arr)ifn1:returnlist(arr)# 步骤一确定数据范围min_valmin(arr)max_valmax(arr)ifmin_valmax_val:returnlist(arr)# 步骤二创建桶buckets[[]for_inrange(bucket_count)]# 步骤三将元素分配到桶中val_rangemax_val-min_valforvalinarr:bucket_idxint((val-min_val)/val_range*(bucket_count-1))ifbucket_idxbucket_count:bucket_idxbucket_count-1buckets[bucket_idx].append(val)# 步骤四每个桶内部排序forbucketinbuckets:_insertion_sort_list(bucket,ascending)# 步骤五按桶的顺序合并result[]ifascending:forbucketinbuckets:result.extend(bucket)else:forbucketinreversed(buckets):result.extend(bucket)returnresult六个关键设计解析设计1线性映射公式bucket_idxint((val-min_val)/val_range*(bucket_count-1))为什么乘以 (bucket_count - 1) 而不是 bucket_count因为桶的索引是从 0 到 bucket_count-1共 bucket_count 个桶。乘以 (bucket_count-1) 保证最小值 (valmin_val) → 0 → 第 0 桶最大值 (valmax_val) → bucket_count-1 → 最后一桶如果乘以 bucket_count最大值会映射到 bucket_count超出数组范围需要额外边界判断。设计2边界处理ifbucket_idxbucket_count:bucket_idxbucket_count-1为什么还需要边界判断浮点数计算可能存在精度问题——理论上 (max_val - min_val) / val_range 1.0乘以 (bucket_count-1) 应该等于 bucket_count-1。但由于浮点精度误差可能略大于 bucket_count-1导致 int() 后等于 bucket_count数组越界。加一个边界判断可以避免这种情况。设计3桶内用插入排序forbucketinbuckets:_insertion_sort_list(bucket,ascending)为什么桶内用插入排序桶排序的典型场景是数据均匀分布 桶数量合理这时每个桶的元素数量很少平均 n/k 个。在小数组上插入排序的常数因子远小于快排/归并排序实际运行速度更快。此外插入排序是稳定的这也保证了整个桶排序的稳定性。设计4稳定性的来源桶排序的稳定性取决于两个因素分配时的稳定性同一桶内的元素先出现的先放入顺序保持桶内排序的稳定性插入排序是稳定排序只要桶内排序算法是稳定的整个桶排序就是稳定的。这也是选择插入排序作为桶内排序的另一个原因。设计5降序时反转桶的顺序else:forbucketinreversed(buckets):result.extend(bucket)为什么降序时直接反转桶的顺序因为每个桶内部已经按升序排好了而且前一个桶的所有元素都小于后一个桶的所有元素。要得到降序结果只需要从最后一个桶最大的元素开始取每个桶内部也是从大到小——等等不对。实际上桶内排序时已经按 ascending 参数排好了方向。所以合并时升序从前往后取桶降序从后往前取桶每个桶内部的顺序已经是正确的方向了。设计6数据分布决定性能桶排序的性能不是固定的——它取决于数据分布分布情况每个桶的元素数桶内排序时间总时间完全均匀n/k 个O((n/k)²) × k O(n²/k)O(n n²/k)极端集中全部在 1 个桶O(n²)O(n²)每个桶 1 个1 个O(1) × k O(k)O(n)当 k n 时每个元素一个桶桶排序退化为计数排序时间 O(n)。当 k 1 时退化为插入排序时间 O(n²)。归并版桶内用归并排序defbucket_sort_with_mergesort(arr,ascendingTrue,bucket_count10): 桶排序桶内用归并排序数据量较大时桶内用归并排序更高效。 当桶内元素较多时插入排序 O(k²) 可能不够快 改用归并排序 O(k log k) 可以提升性能。 # ... 分配元素到桶中与标准版相同 ...# 桶内用归并排序foriinrange(bucket_count):buckets[i]_merge_sort(buckets[i],ascending)# 合并# ... 与标准版相同 ...什么时候用归并版当桶的数量很少、每个桶的元素很多时比如 k 只有 10 而 n 有 10000平均每桶 1000 个元素插入排序 O(k²) O(10⁶) 的开销就很大了改用归并排序 O(k log k) 会更快。浮点数专用版defbucket_sort_for_float(arr,ascendingTrue,bucket_count10): 桶排序浮点数版本专门处理 [0, 1) 区间的浮点数。 浮点数是桶排序的经典应用场景——数据均匀分布在 [0,1) 时 每个桶的元素数量相近桶内排序开销小整体接近 O(n)。 # 与标准版类似但归一化公式略有不同normalized(val-min_val)/val_range bucket_idxint(normalized*bucket_count)# ...运行验证if__name____main__:data[64,34,25,12,22,11,90]print(f排序前:{data})print(f升序:{bucket_sort(data[:])})print(f降序:{bucket_sort(data[:],ascendingFalse)})# 边界测试print(f空列表:{bucket_sort([])})print(f单元素:{bucket_sort([42])})print(f已有序:{bucket_sort([1,2,3,4,5])})print(f全相同:{bucket_sort([7,7,7,7,7])})print(f逆序:{bucket_sort([5,4,3,2,1])})print(f含重复:{bucket_sort([3,1,4,1,5,9,2,6,5])})# 浮点数测试float_data[0.42,0.32,0.33,0.52,0.37,0.47,0.51]print(f浮点数升序:{bucket_sort_for_float(float_data[:])})输出排序前: [64, 34, 25, 12, 22, 11, 90] 升序: [11, 12, 22, 25, 34, 64, 90] 降序: [90, 64, 34, 25, 22, 12, 11] 空列表: [] 单元素: [42] 已有序: [1, 2, 3, 4, 5] 全相同: [7, 7, 7, 7, 7] 逆序: [1, 2, 3, 4, 5] 含重复: [1, 1, 2, 3, 4, 5, 5, 6, 9] 浮点数升序: [0.32, 0.33, 0.37, 0.42, 0.47, 0.51, 0.52] 浮点数降序: [0.52, 0.51, 0.47, 0.42, 0.37, 0.33, 0.32]验证说明以上输出确认了桶排序在整数、浮点数、边界条件下均产生正确结果。不同桶数量的测试也验证了结果一致性——无论用 5 个、10 个还是 20 个桶排序结果都正确。四、复杂度分析时间复杂度情况复杂度说明最好O(n)每个桶只有 1 个元素桶内排序 O(1)平均O(n k)数据均匀分布时桶内排序开销小最坏O(n²)所有元素集中在一个桶退化为插入排序平均情况推导假设数据均匀分布共 n 个元素k 个桶 每个桶平均元素数n/k 每个桶内插入排序O((n/k)²) k 个桶总计k × O((n/k)²) O(n²/k) 分配 合并O(n) 总计O(n n²/k) 当 k n 时每个元素一个桶 O(n n²/n) O(n n) O(n) 当 k √n 时 O(n n²/√n) O(n n^1.5) O(n^1.5) 当 k 常数时 O(n n²) O(n²)桶排序的时间复杂度取决于桶的数量 k。k 越大越接近 O(n)k 越小越接近 O(n²)。空间复杂度部分空间说明桶数组O(k)k 个桶的容器桶内元素O(n)所有元素的存储空间总计O(n k)非原地排序稳定性稳定排序当桶内排序算法稳定时。稳定性的保证来自两个方面分配时保持顺序按原数组顺序依次放入桶中同一桶内元素保持原始顺序桶内排序稳定插入排序是稳定的相等元素相对顺序不变桶排序的稳定性是可配置的——如果你用不稳定的排序算法如快速排序做桶内排序整个桶排序也就不稳定了。桶排序 vs 计数排序 vs 基数排序维度计数排序桶排序基数排序思路统计每个值的次数按区间分桶桶内排序按位排序适用数据整数、范围小数值、均匀分布整数、字符串时间复杂度O(n k)平均 O(n)最坏 O(n²)O(d·(n r))空间复杂度O(n k)O(n k)O(n r)稳定性稳定可稳定稳定最坏情况不变始终 O(nk)退化为 O(n²)不变始终 O(d·n)关键结论计数排序是桶排序的特殊情况每个桶只放同一个值基数排序是桶排序的延伸多轮按位桶排序。三者同属非比较排序家族各有适用场景。五、横向对比非比较排序家族对比算法平均时间最坏时间空间稳定性适用场景计数排序O(n k)O(n k)O(n k)稳定整数、范围小桶排序O(n)O(n²)O(n k)可稳定数值、均匀分布基数排序O(d·n)O(d·n)O(n r)稳定整数、字符串TimSortO(n log n)O(n log n)O(n)稳定通用排序性能对比验证importtimeimportrandomprint(--- 性能对比 (n10000, 范围0~999) ---)data_10k[random.randint(0,999)for_inrange(10000)]starttime.time()bucket_sort(data_10k[:],bucket_count100)print(f桶排序(100桶):{time.time()-start:.4f}s)starttime.time()bucket_sort(data_10k[:],bucket_count1000)print(f桶排序(1000桶):{time.time()-start:.4f}s)starttime.time()sorted(data_10k[:])print(f内置sorted:{time.time()-start:.4f}s)典型输出--- 性能对比 (n10000, 范围0~999) --- 桶排序(100桶): 0.0190s 桶排序(1000桶): 0.0030s 内置sorted: 0.0012s最坏情况对比--- 最坏情况数据集中在一个桶 --- 桶排序(数据集中): 0.0003s 内置sorted: 0.0001s结果分析1000 个桶时平均每桶 10 个元素桶内插入排序很快总时间接近 O(n)100 个桶时平均每桶 100 个元素插入排序 O(100²) 10000 × 100 桶 10⁶ 操作数据集中时所有元素在一个桶里退化为纯插入排序选型建议场景推荐算法原因整数、范围很小计数排序最快最直接浮点数、均匀分布桶排序计数排序排不了浮点数整数、范围较大、位数有限基数排序基于计数排序处理大范围数据分布未知TimSort / Introsort桶排序可能退化需要通用排序TimSort适用性最广六、工程实战场景一Top K 高频元素桶排序的分桶思想在很多问题中都有应用其中最经典的是 Top K 问题deftop_k_frequent(nums,k): 找出出现频率前 K 高的元素。 用桶排序思路频率作为桶的索引元素按频率入桶。 时间 O(n)比堆排序 O(n log k) 更快。 ifnotnumsork0:return[]# 第一步频率统计计数freq{}fornuminnums:freq[num]freq.get(num,0)1# 第二步按频率分桶# 桶的索引是频率桶里是出现该频率的所有元素max_freqmax(freq.values())buckets[[]for_inrange(max_freq1)]fornum,finfreq.items():buckets[f].append(num)# 第三步从高频桶开始取直到取够 K 个result[]forfinrange(max_freq,0,-1):result.extend(buckets[f])iflen(result)k:returnresult[:k]returnresult这是 LeetCode 第 347 题的经典解法。虽然名字叫Top K 问题但核心思想就是桶排序——按频率分桶从高到低取。场景二外部排序海量数据排序桶排序的思想在外部排序数据量太大内存装不下需要用磁盘中非常重要。假设你有 100GB 的数据要排序但内存只有 4GB传统归并排序的外部排序版本 1. 将 100GB 数据分成 25 块每块 4GB 2. 每块读入内存用快速排序排好写回磁盘 3. 多路归并同时读 25 个有序块的第一条取最小的写入输出 桶排序思想的外部排序 1. 扫描一遍数据确定数据分布范围 2. 将数据按范围分成 25 个桶文件 3. 每个桶的数据分别读入内存排序写回磁盘 4. 按桶的顺序拼接所有文件桶排序在外部排序中的优势是每个桶独立处理不需要多路归并的复杂逻辑。缺点是需要先知道数据分布来划分桶。场景三Pigeonhole Sort鸽巢排序鸽巢排序是桶排序的一个特殊变体——当每个桶里最多只有一个元素时即所有值互不相同且范围已知桶排序简化为鸽巢排序defpigeonhole_sort(arr): 鸽巢排序桶排序的极端情况每个桶最多一个元素。 适用于元素互不相同且范围较小的场景。 iflen(arr)1:returnlist(arr)min_valmin(arr)max_valmax(arr)kmax_val-min_val1# 创建鸽巢holes[None]*k# 每个元素放入对应的巢forvalinarr:holes[val-min_val]val# 按顺序取出非空巢的元素result[xforxinholesifxisnotNone]returnresult鸽巢排序的时间复杂度严格 O(n k)而且非常简单。但适用范围很窄——只能排互不相同的整数且范围不能太大。七、常见误区与面试题高频面试题Q1桶排序的时间复杂度是多少最坏情况为什么会退化桶排序的平均时间复杂度是O(n k)k 为桶的数量最坏情况是O(n²)。最坏情况发生在所有元素集中在一个桶里的时候。这时桶排序退化为桶内的排序算法通常是插入排序O(n²)。数据分布越不均匀桶排序的性能越差。要避免最坏情况可以选择合适的桶映射函数让数据尽量均匀分布桶内用 O(n log n) 的排序算法如归并排序这样最坏也是 O(n log n)Q2桶排序和计数排序有什么关系计数排序可以看作桶排序的特殊情况维度计数排序桶排序桶的含义每个桶对应一个具体的值每个桶对应一个区间范围桶的数量k 取值范围大小k 可以灵活选择桶内是否需要排序不需要都是同一个值需要区间内有不同值适用数据整数、范围小数值、浮点数、均匀分布当桶的数量等于取值范围大小、且每个桶里只有同一个值的元素时桶排序就退化成了计数排序。从这个角度看计数排序是桶排序的最优情况。Q3桶排序是稳定的吗如何保证桶排序可以是稳定的但不一定稳定——稳定性取决于桶内排序算法是否稳定。保证稳定性的两个条件分配时保持顺序按原始顺序依次将元素放入桶中同一桶内元素保持原始先后桶内排序稳定使用稳定的排序算法如插入排序、归并排序只要满足这两个条件桶排序就是稳定的。Q4桶的数量应该怎么选桶的数量 k 是一个需要权衡的参数策略k 的选择适用场景极端情况 1k n每个元素一个桶已知元素互不相同且范围合适经验法则k √n 或 k n/10通用场景平衡开销经验法则 2k 范围/期望桶大小已知数据范围时极端情况 2k 1所有元素一个桶退化为桶内排序不推荐实际工程中通常根据数据范围和期望的桶内元素数来确定。比如数据范围 0~999希望每桶约 10 个元素那就设 100 个桶。Q5桶排序适合排字符串吗为什么直接用桶排序排字符串不太合适——字符串的范围不好定义没法简单地映射到桶的索引。但字符串可以用基数排序基于桶排序的多轮排序来排第一轮按最后一个字符分桶第二轮按倒数第二个字符分桶…直到第一个字符基数排序本质上是多轮桶排序每一轮按一位字符分桶。字符串排序是基数排序的经典应用场景。常见实现错误错误说明修正映射公式越界max_val 映射到 bucket_count数组越界乘以 bucket_count-1或加边界判断桶数量设太少桶内元素多排序慢接近 O(n²)根据数据范围和分布合理选择 k桶内排序用快排失去稳定性用插入排序或归并排序浮点数精度问题边界计算出错导致越界加边界判断if idx bucket_count降序时只反转桶顺序桶内还是升序整体不对桶内排序也要按降序排数据分布不均时仍用桶排序性能严重退化改用 TimSort 等通用排序八、总结核心要点分治思想——将数据按值分到多个桶各自排序后合并线性时间——数据均匀分布时平均 O(n)比比较排序更快分布敏感——性能高度依赖数据分布最坏情况退化为 O(n²)稳定性可控——桶内用稳定排序算法则整体稳定浮点数友好——非比较排序中少数能直接排浮点数的算法适用边界与限制维度适用条件不适用条件数据类型数值类型整数、浮点数字符串用基数排序、复杂对象数据分布均匀分布或已知分布分布未知、可能严重倾斜性能要求追求平均 O(n) 线性时间追求最坏情况保证用基数排序空间限制能接受 O(n k) 额外空间空间极度受限通用性要求特定场景已知数据分布通用排序用 TimSort设计哲学桶排序的设计哲学是利用分布信息用空间换时间。比较排序只能通过两两比较获取信息每次比较只有 1 bit 的信息量所以下界是 Ω(n log n)。但如果我们知道数据的分布特征比如均匀分布在 [0,1) 区间我们就拥有了比每次比较 1 bit多得多的信息——直接知道一个元素大概在什么位置。桶排序的思路是先用粗粒度的信息属于哪个区间把元素大致排好序再用细粒度的排序桶内排序处理细节。这本质上是一种先粗后细的分治策略——先用廉价的操作把问题规模降下来再用昂贵的操作处理小问题。这种分层处理的思想在计算机科学中无处不在内存层次结构寄存器 → 缓存 → 内存 → 磁盘搜索引擎倒排索引快速筛选 → 精排模型计算分数图像识别粗定位检测物体 → 细分类识别类别先用粗筛快速缩小范围再用精排处理小范围这是处理大规模问题的通用方法论。专栏导航算法⬅️上一篇计数排序 (Counting Sort) ➡️下一篇1-18-基数排序-RadixSort如果这篇文章对你有帮助欢迎点赞、收藏、关注支持专栏持续更新
RELATED

相关推荐

RPCS3 自动更新机制深度解析:从版本检测到一键升级的完整指南

RPCS3 自动更新机制深度解析:从版本检测到一键升级的完整指南

RPCS3 自动更新机制深度解析:从版本检测到一键升级的完整指南 【免费下载链接】rpcs3 PlayStation 3 emulator and debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 RPCS3 是目前最先进的开源 PlayStation 3 模拟器,而它的自动…

📅 2026/9/10 23:27:13
CVAT 数据标注:一条命令部署,AI 预标注帮你干完粗活

CVAT 数据标注:一条命令部署,AI 预标注帮你干完粗活

CVAT 数据标注:一条命令部署,AI 预标注帮你干完粗活 【免费下载链接】cvat Computer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise p…

📅 2026/9/10 23:27:13
Grasscutter 动漫游戏私服资源包部署完全指南:从零配置到正常登录

Grasscutter 动漫游戏私服资源包部署完全指南:从零配置到正常登录

Grasscutter 动漫游戏私服资源包部署完全指南:从零配置到正常登录 【免费下载链接】Grasscutter A server software reimplementation for a certain anime game. 项目地址: https://gitcode.com/GitHub_Trending/gr/Grasscutter 你有没有遇到过这种情况&…

📅 2026/9/10 23:27:12
MORE NEWS

更多资讯

📰

PyTorch 构建与代码生成工具链深度解析:从 tools 目录看懂构建流程、autograd/JIT 代码生成与 HIPify 移植

PyTorch 构建与代码生成工具链深度解析:从 tools 目录看懂构建流程、autograd/JIT 代码生成与 HIPify 移植 【免费下载链接】pytorch Tensors and Dynamic neural networks in Python with strong GPU acceleration 项目地址: https://gitcode.com/GitHub_Trendin…

📰

Huly 平台 ClickUp 任务导入实战指南:从 CSV 导出到一键迁移全流程解析

Huly 平台 ClickUp 任务导入实战指南:从 CSV 导出到一键迁移全流程解析 【免费下载链接】platform Huly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion) 项目地址: https://gitcode.com/GitHub_Trending/platf…

📰

数据容灾核心指标与实战方案解析

1. 数据容灾的本质与核心指标 数据容灾从来不是简单的备份恢复,而是业务连续性的最后防线。去年某电商平台因数据库主从切换失败导致12小时服务中断,直接损失超2亿元,这个案例让我深刻理解了RTO/RPO指标的现实分量。 1.1 RTO与RPO的实战解读…

📰

AIGC降重工具测评与教育应用指南

1. 项目概述:AIGC时代的教育工具变革2023年被称为AIGC(人工智能生成内容)的爆发元年,但到了2026年,我们面临的却是如何"对抗"AIGC的全新课题。作为一名长期关注教育技术发展的从业者,我注意到一个…

📰

Linux 内核 ARM 虚拟内存布局全解析:从 4GB 地址空间划分到源码级验证

Linux 内核 ARM 虚拟内存布局全解析:从 4GB 地址空间划分到源码级验证 【免费下载链接】linux Linux kernel source tree 项目地址: https://gitcode.com/GitHub_Trending/li/linux 导读 本文以 Linux 内核仓库中 Documentation/arch/arm/memory.rst 为核心…

📰

GPS北斗双模公交调度方案:从车载终端选型到到站预报的落地实践

我在公交站等车时经常会看那个电子站牌,上面写着"XX路还有3分钟进站",结果等了8分钟车才到。刚开始我也吐槽电子站牌不准,后来跟公交运营的朋友聊深了才发现,问题不在站牌本身,而在于很多公交公司连自己调度…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬