这是我参与「第三届青训营 -后端场」笔记创作活动的的第6篇笔记。 例子,抖音直播排行榜功能: 规则: 某个时间段内,直播间礼物数TOP10房间获得奖励,需要在每个房间展示排行榜。 解决方案: 礼物数量存储在Redis-zset中,使用skiplist使元素整体有序 使用redis集群,避免单机压力过大,使用主从算法,分片算法。 保证集群原信息的稳定,使用一致性算法 后端使用缓存算法(LRU)降低Redis压力 展示房间排行榜
数据结构和算法几乎存在于程序开发中的所有地方。
排序算法一览: 插入排序:
堆排序:
快速排序:
快排的最好时间复杂度是O(nlogn) 最坏时间复杂度是O(n^2)这个主要是看划分的左右子数组是否均衡,要是不均衡,极端情况下就退化为O(n^2)的复杂度了
在实际场景下 短序列和元素有序的情况下,插入排序的性能最好 在大部分情况下,快速排序有一个较好的综合性能 几乎在任何情况下,堆排序的表现都比较稳定
cpp里的sort:数量少的时候用插排 多的时候先用快排 如果快排的时间预估很长 转为堆排
因为堆排最差也是O(nlogn) 比快排的O(n^2)要快一些
pdqsort(pattern-defeating-quicksort): 是一种不稳定的混合排序算法,它的不同版本被应用在C++ BOOTS、Rust以及Go 1.19中。 它对常见的序列类型做了特殊的优化,使得在不同条件下都拥有不错的性能。
结合三种排序方法的优点: 对于短序列(小于一定长度)我们使用插入排序,其他情况使用快速排序保证整体性能, 当快速排序表现不佳时,使用堆排序来保证最坏情况下时间复杂度仍然为O(n*logn)
说明: 1、短序列一般指12-32之间 在go的泛型版本根据测试选定24 2、如何得知快速排序表现不佳,以及何时切换到堆排序? 当最终pivot的位置离两端很接近时(距离小于length/8),这个情况会导致分割不均匀。当这种情况次数达到limit时,即(bits.Len(length))时,切换到堆排序。