使用 JS 实现 B树或多路平衡查找树

97 min read

B树是一种多路平衡查找树,它的节点可以存储更多的数据,因此在查找过程中可以减少磁盘的IO次数,提高查找效率。下面是使用JS实现B树的代码:

class BTreeNode {
  constructor(m, isLeaf) {
    this.m = m; // 最大度数
    this.keys = []; // 存储关键字的数组
    this.children = []; // 存储子节点的数组
    this.isLeaf = isLeaf || false; // 是否为叶子节点
  }
  
  // 在当前节点中查找key的位置
  findIndex(key) {
    let i = 0;
    while (i < this.keys.length && this.keys[i] < key) {
      i++;
    }
    return i;
  }
  
  // 在当前节点中插入key和value
  insert(key, value) {
    let i = this.findIndex(key);

    // 如果当前节点是叶子节点
    if (this.isLeaf) {
      this.keys.splice(i, 0, key);
      this.children.splice(i, 0, value);
      return this;
    }

    // 如果当前节点不是叶子节点
    let child = this.children[i];
    if (child.keys.length === 2 * this.m - 1) {
      this.splitChild(i);
      if (key > this.keys[i]) {
        i++;
      }
    }
    this.children[i].insert(key, value);
    return this;
  }
  
  // 分裂子节点
  splitChild(i) {
    let child = this.children[i]; // 待分裂的子节点
    let newNode = new BTreeNode(this.m, child.isLeaf);
    let mid = Math.floor(child.keys.length / 2);
    let splitKey = child.keys[mid]; // 中间的关键字

    newNode.keys = child.keys.splice(mid + 1);
    newNode.children = child.children.splice(mid + 1);

    this.keys.splice(i, 0, splitKey);
    this.children.splice(i + 1, 0, newNode);
  }
  
  // 在当前节点中查找key对应的value
  find(key) {
    let i = this.findIndex(key);

    // 如果当前节点是叶子节点,则查找结束
    if (this.isLeaf) {
      return this.keys[i] === key ? this.children[i] : null;
    }

    // 如果当前节点不是叶子节点,继续向下查找
    let child = this.children[i];
    return child.find(key);
  }
  
}

class BTree {
  constructor(m) {
    this.root = new BTreeNode(m, true); // 创建树的根节点
    this.m = m; // 最大度数
  }
  
  // 在树中插入key和value
  insert(key, value) {
    if (this.root.keys.length === 2 * this.m - 1) { // 根节点已满,需要分裂
      let newRoot = new BTreeNode(this.m, false);
      newRoot.children.push(this.root);
      newRoot.splitChild(0);
      this.root = newRoot;
    }
    this.root.insert(key, value);
  }
  
  // 在树中查找key对应的value
  find(key) {
    return this.root.find(key);
  }
  
}

以上是使用JS实现B树的代码,可以通过以下方式使用B树:

let tree = new BTree(2); // 创建度数为2的B树
tree.insert(5, "value1");
tree.insert(3, "value2");
tree.insert(8, "value3");
console.log(tree.find(3)); // 输出"value2"
console.log(tree.find(5)); // 输出"value1"
console.log(tree.find(8)); // 输出"value3"