You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SortedSet SkipList插入时如何更新指针长度以实现O(logn)的get(index)

为SortedSet跳表实现O(logn)时间复杂度的get(index)的插入逻辑改造

要让get(index)达到O(logn),核心是给跳表的每个节点增加**length数组**,与next数组一一对应。length[r]的定义是:在第r层中,当前节点的next[r]节点与自身的底层索引差值(即从当前节点沿next[r]跳转,会跨越多少个元素)。这样在查询索引时,就能通过累加各层的length值快速定位目标位置。

以下是针对你现有插入逻辑的具体修改步骤:

1. 补充遍历过程中的索引计算与路径记录

首先需要在遍历过程中累加索引,同时记录每一层前驱节点的索引(用于后续更新length)。修改原遍历循环:

// 新增数组记录各层前驱节点的底层索引
int[] indexStack = new int[stack.length]; // 假设stack已初始化足够长度
Node<T> u = sentinel;
int r = h;
int comp = 0;
int j = -1; // sentinel的底层索引为-1
Node<T> w = new Node<>(x, pickHeight());

while (r >= 0) {
    while (u.next[r] != null && (comp = c.compare(u.next[r].x, x)) < 0) {
        // 累加当前层的length,得到下一个节点的索引偏移
        j += u.length[r];
        u = u.next[r];
    }
    // 记录当前层的前驱节点及其索引
    stack[r] = u;
    indexStack[r] = j;
    r--;
    
    // 遇到重复元素直接返回
    if (r+1 >=0 && u.next[r+1] != null && comp == 0) {
        return false;
    }
}
int wIndex = j + 1; // 新节点的底层索引

2. 处理跳表高度扩展

当新节点高度超过当前跳表高度时,需要初始化新层的哨兵节点length:

while (h < w.height()) {
    stack[++h] = sentinel;
    indexStack[h] = -1; // 哨兵的索引始终为-1
    // 新层哨兵的length为总元素数(插入后),因为哨兵到末尾共n+1个元素
    sentinel.length[h] = n + 1;
}

3. 插入节点并更新length数组

插入新节点时,需要先保存前驱节点原有的length值,再拆分更新前驱和新节点的length:

for (int i = 0; i < w.next.length; i++) {
    Node<T> prev = stack[i];
    Node<T> nextNode = prev.next[i];
    int prevIndex = indexStack[i];
    
    // 保存前驱节点原有的length值
    int oldPrevLength = prev.length[i];
    
    // 插入新节点的next指针
    w.next[i] = nextNode;
    prev.next[i] = w;
    
    // 更新前驱节点的length:现在指向新节点,差值为新节点索引 - 前驱索引
    prev.length[i] = wIndex - prevIndex;
    
    // 更新新节点的length:拆分原前驱的length,剩余部分指向后继节点
    if (nextNode != null) {
        w.length[i] = oldPrevLength - (wIndex - prevIndex);
    } else {
        // 无后继节点时,length为总元素数 - 新节点索引
        w.length[i] = (n + 1) - wIndex;
    }
}

n++; // 最后更新节点总数
return true;

关键注意事项

  • 节点结构要求:你的Node<T>类必须新增int[] length成员,初始化时与next数组长度一致。
  • length定义一致性:所有层的length都基于底层索引计算,确保跨层跳转时的索引累加逻辑正确。
  • 重复元素判断:必须在遍历过程中提前检测重复元素,避免后续无效的length更新。

内容的提问来源于stack exchange,提问作者32_Quốc Vinh_11A13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:35:55