当前位置:首页 > JavaScript

跳表实现 js

2026-03-02 07:32:58JavaScript

跳表实现 JavaScript

跳表(Skip List)是一种概率性的数据结构,允许快速查询、插入和删除操作,时间复杂度为O(log n)。以下是JavaScript实现跳表的方法:

定义节点类

每个节点包含值、指向下一个节点的指针数组以及节点的层级。

class Node {
  constructor(value, level) {
    this.value = value;
    this.next = new Array(level).fill(null);
  }
}

跳表类实现

跳表类需要初始化最大层级、当前层级、头节点和概率因子(通常为0.5)。

跳表实现 js

class SkipList {
  constructor() {
    this.maxLevel = 16;
    this.currentLevel = 1;
    this.head = new Node(null, this.maxLevel);
    this.probability = 0.5;
  }
}

随机层级生成

插入节点时随机生成层级,确保跳表的平衡性。

_randomLevel() {
  let level = 1;
  while (Math.random() < this.probability && level < this.maxLevel) {
    level++;
  }
  return level;
}

查找操作

从最高层开始查找,逐步向下缩小范围。

跳表实现 js

search(value) {
  let current = this.head;
  for (let i = this.currentLevel - 1; i >= 0; i--) {
    while (current.next[i] !== null && current.next[i].value < value) {
      current = current.next[i];
    }
  }
  current = current.next[0];
  return current !== null && current.value === value ? current : null;
}

插入操作

找到插入位置并更新各层指针。

insert(value) {
  const update = new Array(this.maxLevel).fill(null);
  let current = this.head;

  for (let i = this.currentLevel - 1; i >= 0; i--) {
    while (current.next[i] !== null && current.next[i].value < value) {
      current = current.next[i];
    }
    update[i] = current;
  }

  const level = this._randomLevel();
  if (level > this.currentLevel) {
    for (let i = this.currentLevel; i < level; i++) {
      update[i] = this.head;
    }
    this.currentLevel = level;
  }

  const newNode = new Node(value, level);
  for (let i = 0; i < level; i++) {
    newNode.next[i] = update[i].next[i];
    update[i].next[i] = newNode;
  }
}

删除操作

找到目标节点并更新各层指针。

delete(value) {
  const update = new Array(this.maxLevel).fill(null);
  let current = this.head;

  for (let i = this.currentLevel - 1; i >= 0; i--) {
    while (current.next[i] !== null && current.next[i].value < value) {
      current = current.next[i];
    }
    update[i] = current;
  }

  current = current.next[0];
  if (current === null || current.value !== value) return false;

  for (let i = 0; i < this.currentLevel; i++) {
    if (update[i].next[i] !== current) break;
    update[i].next[i] = current.next[i];
  }

  while (this.currentLevel > 1 && this.head.next[this.currentLevel - 1] === null) {
    this.currentLevel--;
  }
  return true;
}

示例用法

创建跳表实例并执行操作。

const skipList = new SkipList();
skipList.insert(3);
skipList.insert(6);
skipList.insert(7);
skipList.insert(9);
console.log(skipList.search(6)); // 返回节点
skipList.delete(6);
console.log(skipList.search(6)); // 返回null

复杂度分析

  • 查找、插入、删除的平均时间复杂度均为O(log n)
  • 空间复杂度为O(n log n),最坏情况下可能达到O(n^2)

注意事项

  • 跳表性能依赖于随机层级生成,确保概率因子合理
  • 实际应用中可根据数据规模调整maxLevel值
  • 跳表相比平衡树实现更简单,适合需要高效动态操作的场景

标签: js
分享给朋友:

相关文章

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swipe…

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClipb…

js实现换肤

js实现换肤

使用CSS变量实现换肤 通过CSS变量可以轻松实现主题切换功能。CSS变量在根元素中定义,通过JavaScript动态修改这些变量值。 :root { --primary-color: #349…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现求导

js实现求导

实现数值求导的方法 在JavaScript中实现求导通常采用数值方法,因为JavaScript不是符号计算语言。以下是常见的数值微分方法: 中心差分法 中心差分法提供较高精度的导数近似: func…

js实现授权

js实现授权

授权流程设计 授权流程通常涉及前端与后端的交互,常见方案包括OAuth2.0、JWT等。以JWT为例的典型流程: 用户提交凭证(如用户名密码)到认证服务 服务端验证通过后生成包含用户信息的J…