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

如何基于Vector实现按ID排序的二叉搜索树节点插入功能?

嘿,我懂你想用vector来实现一个按ID排序的二叉搜索树(把根节点放在索引1的位置),这种用数组结构模拟二叉树的思路挺有意思的,下面我一步步给你拆解插入函数的实现逻辑和代码:

先明确基础定义

首先咱们得先把Node结构体和存储用的vector准备好,这里注意把vector的索引0留空,根节点放在索引1的位置,这样方便计算左右孩子的索引:

#include <vector>
#include <string>
#include <iostream>

// 定义节点结构
struct Node {
    int ID;
    int age;
    std::string Name;

    // 构造函数,方便快速创建新节点
    Node(int id = 0, int a = 0, std::string name = "") : ID(id), age(a), Name(std::move(name)) {}
};

// 存储二叉树的vector,索引0占位,根在索引1
std::vector<Node> bst;
插入函数的核心逻辑

用vector模拟二叉搜索树时,咱们遵循完全二叉树的索引规则:

  • 索引为i的节点,左孩子索引是2*i
  • 右孩子索引是2*i + 1

插入的核心就是按照BST的规则(小ID往左,大ID往右)找到合适的空位置,然后把新节点放进去,具体步骤如下:

步骤1:处理空树情况

如果vector是空的,直接把新节点放到索引1的位置,记得先给vector扩容到能容纳索引1的大小。

步骤2:从根节点开始遍历找位置

从索引1的根节点出发,不断比较新节点和当前节点的ID:

  • 新ID更小 → 往左子树走,检查左孩子索引是否有效,无效就扩容vector
  • 新ID更大 → 往右子树走,同样检查索引有效性
  • ID相等 → 处理重复(比如提示报错,或者根据需求覆盖)

步骤3:插入新节点

找到空的索引位置后,把新节点赋值过去即可。

完整的插入函数代码
void insertNode(int id, int age, std::string name) {
    Node newNode(id, age, name);

    // 空树的情况:直接初始化根节点
    if (bst.empty()) {
        // 索引0留空,所以resize到2,索引1放根节点
        bst.resize(2);
        bst[1] = newNode;
        return;
    }

    int currentIdx = 1;
    while (true) {
        if (newNode.ID < bst[currentIdx].ID) {
            // 左孩子索引
            int leftIdx = 2 * currentIdx;
            // 如果索引超出当前vector大小,先扩容
            if (leftIdx >= bst.size()) {
                bst.resize(leftIdx + 1);
            }
            // 检查该位置是否为空(这里用ID=0标记空节点,如果你允许ID为0,可以换个标记,比如加个bool isValid成员)
            if (bst[leftIdx].ID == 0) {
                bst[leftIdx] = newNode;
                break;
            } else {
                // 左孩子有节点,继续往左遍历
                currentIdx = leftIdx;
            }
        } else if (newNode.ID > bst[currentIdx].ID) {
            // 右孩子索引
            int rightIdx = 2 * currentIdx + 1;
            if (rightIdx >= bst.size()) {
                bst.resize(rightIdx + 1);
            }
            if (bst[rightIdx].ID == 0) {
                bst[rightIdx] = newNode;
                break;
            } else {
                // 右孩子有节点,继续往右遍历
                currentIdx = rightIdx;
            }
        } else {
            // ID重复的情况,按需处理
            std::cout << "Error: ID " << id << " already exists!" << std::endl;
            break;
        }
    }
}
额外补充说明
  • 空节点标记优化:上面用ID=0标记空节点,如果你的业务场景允许ID为0,建议给Node加一个bool isValid成员,默认是false,插入时设为true,判断空节点就用这个成员,更安全。
  • 空间浪费问题:这种实现如果插入的ID是有序的(比如1,2,3,4...),会导致树退化成链表,vector会被扩到很大但很多位置是空的,不过你说不需要考虑平衡,这个问题就不用在意啦。
  • 默认构造函数:我给Node加了默认构造函数,因为vector扩容时会默认构造新元素,如果你不想加默认构造,可以用std::vector<std::optional<Node>>来存储,空位置用std::nullopt表示,这样更优雅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:57:08