跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

二叉树重建与完全二叉树判定实战

二叉树重建与完全二叉树判定涉及递归分治与广度优先搜索两种核心策略。利用前序和中序序列可唯一还原树结构,关键在于根节点定位与子树划分;判断完全二叉树则需通过层序遍历监测节点空缺情况。文中提供完整 C++ 实现及边界条件处理方案,适合数据结构学习与面试参考。

ServerBase发布于 2024/12/24更新于 2026/7/2039 浏览
二叉树重建与完全二叉树判定实战

前言

二叉树是数据结构中最基础也最重要的结构之一。在实际开发或面试中,我们经常遇到两个经典问题:如何根据遍历序列还原树的结构,以及如何判断一棵树是否满足完全二叉树的性质。下面结合 C++ 代码,聊聊这两个问题的核心思路。

从前序和中序遍历重建二叉树

给定前序遍历(Preorder)和中序遍历(Inorder)序列,我们可以唯一确定一棵二叉树。关键在于前序遍历的第一个元素一定是根节点。找到这个根节点在中序遍历中的位置后,左边就是左子树,右边是右子树。通过递归处理左右区间,就能完成整棵树的构建。

实现时需要注意索引的传递,避免重复计算。下面是具体的 C++ 实现:

#include <iostream>
#include <vector>

struct BinaryTreeNode {
    int value;
    BinaryTreeNode* left;
    BinaryTreeNode* right;
    BinaryTreeNode(int x) : value(x), left(nullptr), right(nullptr) {}
};

// 递归构建函数
BinaryTreeNode* buildTree(const std::vector<int>& preorder, const std::vector<int>& inorder, int& preIndex, int inStart, int inEnd) {
    if (inStart > inEnd) return nullptr;

    BinaryTreeNode* root = new BinaryTreeNode(preorder[preIndex++]);
    int inIndex = -1;

    // 在中序遍历中寻找根节点位置
    for (int i = inStart; i <= inEnd; ++i) {
        if (inorder[i] == root->value) {
            inIndex = i;
            break;
        }
    }

    root->left = buildTree(preorder, inorder, preIndex, inStart, inIndex - );
    root->right = (preorder, inorder, preIndex, inIndex + , inEnd);
     root;
}

{
     preIndex = ;
     (preorder, inorder, preIndex, , <>(inorder.()) - );
}

{
     (node == ) ;
    (node->left);
    std::cout << node->value << ;
    (node->right);
}
1
buildTree
1
return
BinaryTreeNode* rebuildTree(const std::vector<int>& preorder, const std::vector<int>& inorder)
int
0
return
buildTree
0
static_cast
int
size
1
void printInorder(BinaryTreeNode* node)
if
nullptr
return
printInorder
" "
printInorder

这里用到了引用传递 preIndex,确保在递归过程中能正确推进前序数组的下标。

检查二叉树是否为完全二叉树

完全二叉树的定义比较严格:除了最后一层,其他层必须满,且最后一层节点靠左排列。判断时,通常采用层序遍历(BFS)。一旦遇到某个节点缺少子节点,后续所有节点都必须是叶子节点,否则就不是完全二叉树。

具体逻辑如下:

  1. 使用队列进行层序遍历。
  2. 设置标志位 mustHaveNoChild,表示是否遇到了'非满'节点。
  3. 如果标志位为真,后续节点不能有子节点。
  4. 如果遇到左空右非空的情况,直接返回 false。
#include <queue>

bool isCompleteBinaryTree(BinaryTreeNode* pRoot) {
    if (pRoot == nullptr) return false;

    std::queue<BinaryTreeNode*> q;
    q.push(pRoot);
    bool mustHaveNoChild = false;

    while (!q.empty()) {
        BinaryTreeNode* pNode = q.front();
        q.pop();

        if (mustHaveNoChild) {
            if (pNode->left != nullptr || pNode->right != nullptr) return false;
        } else {
            if (pNode->left != nullptr && pNode->right != nullptr) {
                q.push(pNode->left);
                q.push(pNode->right);
            } else if (pNode->left != nullptr && pNode->right == nullptr) {
                mustHaveNoChild = true;
                q.push(pNode->left);
            } else if (pNode->left == nullptr && pNode->right != nullptr) {
                return false;
            } else {
                mustHaveNoChild = true;
            }
        }
    }
    return true;
}

小结

这两个例子展示了二叉树操作的典型模式:递归分治与广度优先搜索。理解它们背后的逻辑比死记代码更重要,特别是在处理边界条件时,比如空指针检查和索引越界,往往决定了程序的健壮性。

目录

  1. 前言
  2. 从前序和中序遍历重建二叉树
  3. 检查二叉树是否为完全二叉树
  4. 小结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • MambaRefine-YOLO:一种用于无人机影像的双模态小目标检测器
  • 基于 Zynq FPGA 的 SD NAND 测试
  • 利用无监督学习为大语言模型实现信息记忆与微调
  • JVM 内存模型详解:运行时数据区结构解析
  • Java 动态代理核心原理与实战
  • 大模型与 RAG 技术全面解析
  • DataAgent:基于 Spring AI Alibaba Graph 的企业级智能数据分析 Agent
  • 基于 AutoGen 框架快速构建 AI Agent 实现自动化绘图任务
  • Llama-2-7b 在昇腾 NPU 上的六大核心场景性能基准
  • PHP 批量混淆加密工具:四种强度与实战指南
  • 通义万相 2.1 API 集成与 Python 图像文本生成实战
  • 旧安卓手机部署 Typecho 博客并实现外网访问
  • Git 安装配置及 IntelliJ IDEA 集成使用指南
  • Python 爬虫核心库 Requests 使用指南
  • SpringBoot+Vue 无人智慧超市管理系统设计与实现
  • 基于 Rokid 灵珠平台搭建旅游 AR 智能体
  • set 与 map 底层实现及高频算法实战
  • Python 性能分析实战:从 cProfile 到火焰图,精准定位瓶颈
  • Spring Boot + Vue 实战:基于 WebSocket 的实时对战匹配系统
  • SpringBoot 统一异常处理

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online