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

如何在二叉树中序遍历指定索引位置实现O(logn)高效插入元素

解法思路

如果坚持要维护原始无规则二叉树的结构,不可能做到O(logn)的插入复杂度,因为原始树没有任何索引信息,每次找插入位置都需要遍历至少O(n)个节点。实际上你的需求本质是动态维护一个支持按索引插入、按索引查询的线性序列,原始二叉树的结构是无关干扰项,不需要实际构建,直接用带size域的平衡二叉搜索树(名次树)即可实现两个操作均为O(logn)的时间复杂度。


具体实现方案

用带附加信息的AVL树(或Treap、Splay树均可)作为底层数据结构,每个节点存储以下信息:

  • 节点存储的值val
  • 左子树的节点总数left_cnt
  • 节点高度(用于AVL树平衡调整)
  • 左右子节点指针

核心操作实现

1. 按索引查询元素

要查询第k个索引的元素,遍历规则如下:

  • 若k == 当前节点的left_cnt:当前节点的val就是目标结果
  • 若k < 当前节点的left_cnt:递归查询左子树的第k个元素
  • 若k > 当前节点的left_cnt:递归查询右子树的第k - left_cnt - 1个元素

2. 按索引插入元素

要在第i个索引插入值为num的节点:

  • 按照上述查询规则找到插入位置,插入新节点
  • 回溯过程中更新路径上所有节点的left_cnt和高度值
  • 出现不平衡时执行AVL树的旋转操作,旋转完成后同步更新受影响节点的left_cnt值

原O(n)逻辑适配

你给出的参考实现中特殊的-1空位逻辑可以直接适配:

  • 若插入的index >= 整棵树的总节点数:先循环插入值为-1的节点到序列末尾,直到总节点数等于index,再插入值为num的节点
  • 若插入位置的原有值为-1:直接修改对应位置节点的val为num即可,不需要执行移位操作

核心代码示例(简化版)

// 节点定义
struct Node {
    int val, height, left_cnt;
    Node *left, *right;
    Node(int v) : val(v), height(1), left_cnt(0), left(nullptr), right(nullptr) {}
};

// 获取节点高度
int getHeight(Node* node) { return node ? node->height : 0; }
// 获取节点子树总大小(左子树+右子树+自身)
int getSize(Node* node) { return node ? node->left_cnt + getSize(node->right) + 1 : 0; }

// 右旋转操作,旋转后更新left_cnt
Node* rightRotate(Node* y) {
    Node* x = y->left;
    Node* T2 = x->right;
    x->right = y;
    y->left = T2;
    // 更新节点高度
    y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
    x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
    // 更新left_cnt计数
    y->left_cnt = getSize(y->left);
    x->left_cnt = getSize(x->left);
    return x;
}

// 左旋转、平衡判断、插入逻辑的完整实现可参照上述规则补充

内容的提问来源于stack exchange,提问作者Zantorym

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:21:01