优化链表查询效率
前言
链表在操作的时候需要从头节点遍历到目标节点,如果数据量大比较耗时。当链表应用在 AOI 算法(十字链表,双有序链表)时这个效率问题更会凸显,最坏的情况是遍历 x*y*{v}个节点。
优化方案
常见的 2 种优化方式:
- 快慢针
创建 2 个指针同时指向头节点,快指针移动步长大、慢指针移动步长小,查询时通过快慢指针确定目标节点的范围。
- 跳表
链表每固定步长的节点为索引节点,这些索引节点再组成一个索引链表,查询时通过索引链表确定目标节点的范围。
原理类似 ClickHouse 的跳数索引
,可以存在多个索引链表。
快慢针
假设一个从小到大的有序链表,检索流程
创建 2 个指针同时指向头节点
快指针移动一次
检查目标节点值是否小于快指针的节点值
小于,把慢指针的位置移动到快指针的位置,从步骤 2 继续执行。
大于,说明目标节点值在慢指针的节点位置和快指针的节点位置中间,从慢指针开始遍历。
快慢针实现简单,且不需要修改链表结构。但查询效率不够稳定,与链表数据大小、快慢针步长的设计有一定关系。
链表结构
1 | type Aoi struct { |
x 轴插入节点(y 轴逻辑一致)
1 | func (r *Aoi) addX(targetNode *node) { |