数据结构算法 | 青训营笔记

45 阅读2分钟

算法应用

例:某时间内,统计直播间礼物top10排行榜

  • 礼物存储在Redis-zset中,使用skiplist使得元素整体有序
  • 使用redis集群,避免单机压力过大,使用主从、分片算法
  • 保证集群原信息的稳定,使用 一致性算法
  • 后端采用LRU降低Redis压力

几个经典排序算法

理论分析

BestAcgWorst
Insertion SortO(n)O(n)O(n2)O(n^2)O(n2)O(n^2)
Quick SortO(nlogn)O(n*\log n)O(nlogn)O(n*\log n)O(n2)O(n^2)
Heap SortO(nlogn)O(n*\log n)O(nlogn)O(n*\log n)O(nlogn)O(n*\log n)

实际场景中,序列元素有几种情况

  1. 完全随机
  2. 有序(逆序)的情况
  3. 元素重复度高
  4. 序列有短、中、长等

实际测试中,以上三种代表性算法在

  • 短序列中,插入排序速度最快
  • 快速排序在多数情况下性能较好
  • 所有情况下堆排序的表现都比较稳定
  • 插入排序已经有序的情况下速度最快

综合上述三个算法做到

arxiv.org/pdf/2106.05…

BestAcgWorst
pdqSortO(n)O(n)O(nlogn)O(n*\log n)O(nlogn)O(n* \log n)

pdqSort

Pattern-defeating-quicksort一种不稳定的混合排序算法。它的不同版本用在C++ BOOST、Rust以及Go1.19中。

策略

  • 对于短序列(11~32,泛型版本采用24),使用插入排序
  • 其他情况,快速排序来保证整体性能
    • pivot尽量为序列的中位数
      • 在随意选择(性能差)和寻找最优(效率低)之间平衡
        • 短序列,选择固定元素
        • 中序列,采样三个元素,近似中位数
        • 长序列,采样九个元素,近似中位数
      • 采样发现序列可能逆序reverse,可能顺序在变更为限制性插入排序
    • Partition更快
  • 快速排序遇到最快情况时,采用堆排序来替换
    • 当pivot位置离序列两端接近时判定表现不佳
  • 元素重复度高
    • 两次Partion生成的pivot相同,则认为pivot的值为重复元素
    • 将重复元素排列在一起,减少重复元素对于pivot选择干扰
  • Pivot选择策略表现不佳随机交换元素
    • 避免极端情况表现不佳,以及黑客攻击

  • 总体来说,工业级的算法是在当前研究成果的基础上,结合实际的应用场景的数据和需求,做出满足的设计
  • 实际上,该pdqSort示例也是设计的一种通用混合算法,针对特定问题和场景肯定还有很多优化的空间
  • 因此,业务中实际使用的算法需要根据场景和面临的问题做出相应的改动,并且最坏情况在某些业务中是需要重点被考虑的(安全问题)