跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C算法

链式二叉树详解:递归遍历与核心接口实现

深入解析链式二叉树的递归实现。涵盖节点结构定义、前中后序遍历逻辑、以及统计节点数、求深度、查找等核心接口。重点剖析递归思想在树形结构中的应用,对比全局变量与传参法的优劣,并补充层序遍历与完全二叉树判断的队列解法。通过实战代码演示,帮助读者掌握二叉树操作精髓,建立清晰的递归思维模型。

刀狂发布于 2026/3/15更新于 2026/5/77 浏览
链式二叉树详解:递归遍历与核心接口实现

链式二叉树详解:递归遍历与核心接口实现

一、结构定义

1.1 概念

链式二叉树使用链表结构来表示,每个节点包含数据域和左右指针域。左指针指向左子树根节点,右指针指向右子树根节点。

1.2 基本结构

链式二叉树的节点由三部分构成:存储数据的变量、指向左孩子的指针、指向右孩子的指针。这种结构天然具有递归性:一棵二叉树由根节点、左子树(本身也是二叉树)和右子树(本身也是二叉树)组成。

// 定义链式二叉树的结构
typedef int BTDataType;
typedef struct BinaryTreeNode {
    BTDataType data;              // 存储数据
    struct BinaryTreeNode* left;  // 指向左孩子节点
    struct BinaryTreeNode* right; // 指向右孩子节点
} BTNode;

二、遍历接口实现

二叉树的操作大多基于递归思想。处理整棵树和处理其子树的方法是一致的。

遍历方式描述
前序遍历根 -> 左 -> 右
中序遍历左 -> 根 -> 右
后序遍历左 -> 右 -> 根
层序遍历按深度从上到下、从左到右访问

2.1 前序遍历

思路: 先访问当前节点,再递归遍历左子树,最后递归遍历右子树。若节点为空则返回。

void PreOrder(BTNode* root) {
    if (root == NULL) {
        printf("NULL ");
        return;
    }
    printf("%c ", root->data);
    PreOrder(root->left);
    PreOrder(root->right);
}

2.2 中序遍历

思路: 先递归遍历左子树,再访问当前节点,最后递归遍历右子树。

void InOrder(BTNode* root) {
    if (root == NULL) {
        printf("NULL ");
        return;
    }
    InOrder(root->left);
    printf("%c ", root->data);
    InOrder(root->right);
}

2.3 后序遍历

思路: 先递归遍历左子树,再递归遍历右子树,最后访问当前节点。

void PostOrder(BTNode* root) {
    if (root == NULL) {
        printf("NULL ");
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%c ", root->data);
}

三、其他核心接口

为了方便演示,我们假设已有一个构建好的二叉树。

3.1 构造二叉树

动态开辟空间并建立节点间的链接关系。

BTNode* buyNode(char x) {
    BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
    newnode->data = x;
    newnode->left = newnode->right = NULL;
    return newnode;
}

BTNode* createTree() {
    BTNode* nodeA = buyNode('A');
    BTNode* nodeB = buyNode('B');
    BTNode* nodeC = buyNode('C');
    BTNode* nodeD = buyNode('D');
    BTNode* nodeE = buyNode('E');
    BTNode* nodeF = buyNode('F');
    nodeA->left = nodeB; nodeA->right = nodeC;
    nodeB->left = nodeD; nodeB->right = nodeE;
    nodeC->left = nodeF;
    return nodeA;
}

3.2 统计有效节点个数

正确方法: 利用返回值累加。总数 = 1 + 左子树节点数 + 右子树节点数。

int BinaryTreeSize(BTNode* root) {
    if (root == NULL) return 0;
    return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

错误示例: 使用全局变量或静态变量。递归调用会共享同一份状态,导致多次调用时计数累加错误,且无法重置。

低效示例: 传参修改。虽然可行,但破坏了函数接口的纯粹性,每次调用前需手动初始化计数器。

3.3 统计叶子节点个数

叶子节点定义为左右孩子均为空的节点。

int BinaryTreeLeafSize(BTNode* root) {
    if (root == NULL) return 0;
    if (root->left == NULL && root->right == NULL) return 1;
    return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

3.4 求第 k 层节点个数

当 k=1 时到达目标层,返回 1;否则递归向下传递 k-1。

int BinaryTreeLevelKSize(BTNode* root, int k) {
    if (root == NULL) return 0;
    if (k == 1) return 1;
    return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

3.5 求树的高度/深度

高度为左右子树最大高度加 1。

int BinaryTreeDepth(BTNode* root) {
    if (root == NULL) return 0;
    int leftHeight = BinaryTreeDepth(root->left);
    int rightHeight = BinaryTreeDepth(root->right);
    return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}

3.6 查找指定节点

匹配根节点数据,若未找到则分别在左右子树中搜索。一旦左子树找到结果,直接返回,无需遍历右子树。

BTNode* BinaryTreeFind(BTNode* root, BTDataType x) {
    if (root == NULL) return NULL;
    if (root->data == x) return root;
    BTNode* leftFind = BinaryTreeFind(root->left, x);
    if (leftFind) return leftFind;
    return BinaryTreeFind(root->right, x);
}

3.7 层序遍历

层序遍历属于广度优先搜索,通常借助队列实现。将根节点入队,循环取出队头并打印,将其非空的孩子节点依次入队。

void LevelOrder(BTNode* root) {
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q)) {
        BTNode* top = QueueFront(&q);
        printf("%c ", top->data);
        QueuePop(&q);
        if (top->left) QueuePush(&q, top->left);
        if (top->right) QueuePush(&q, top->right);
    }
    QueueDestroy(&q);
}

3.8 判断完全二叉树

利用队列进行层序遍历。遇到第一个空节点后,后续出队的节点必须全部为空,否则不是完全二叉树。

bool BinaryTreeComplete(BTNode* root) {
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q)) {
        BTNode* top = QueueFront(&q);
        QueuePop(&q);
        if (top == NULL) break;
        QueuePush(&q, top->left);
        QueuePush(&q, top->right);
    }
    while (!QueueEmpty(&q)) {
        BTNode* top = QueueFront(&q);
        QueuePop(&q);
        if (top != NULL) {
            QueueDestroy(&q);
            return false;
        }
    }
    QueueDestroy(&q);
    return true;
}

总结

链式二叉树是理解递归思维的绝佳范例。通过前序、中序、后序遍历,我们可以用简洁的代码探索整棵树;通过节点统计、深度计算等操作,学会将复杂问题分解为相似子问题。掌握这些基础操作,不仅是学习数据结构的关键,更是培养递归思维、应对更复杂树形结构的基础。

目录

  1. 链式二叉树详解:递归遍历与核心接口实现
  2. 一、结构定义
  3. 1.1 概念
  4. 1.2 基本结构
  5. 二、遍历接口实现
  6. 2.1 前序遍历
  7. 2.2 中序遍历
  8. 2.3 后序遍历
  9. 三、其他核心接口
  10. 3.1 构造二叉树
  11. 3.2 统计有效节点个数
  12. 3.3 统计叶子节点个数
  13. 3.4 求第 k 层节点个数
  14. 3.5 求树的高度/深度
  15. 3.6 查找指定节点
  16. 3.7 层序遍历
  17. 3.8 判断完全二叉树
  18. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • HY-Motion 1.0 基于 Windows WSL2 部署 Gradio WebUI 全流程
  • 大模型推理框架 llama.cpp 开发流程与常用函数解析
  • RaNER 模型 WebUI 使用指南:AI 智能实体侦测实战
  • 垂直行业定制 Llama-Guard 3 守卫模型微调实战
  • AI 模型可解释性与安全防护结合实践
  • C++ string 类详解:概念、常用操作与实践
  • OpenClaw 完整指南:从零搭建 AI 助理
  • 数据结构:带头双向循环链表详解与实现
  • Kohya's GUI 教程:Stable Diffusion 模型训练与 LoRA 定制
  • 2025 年技术博客创作总结:AI 与 WebGIS 探索
  • Stable-Diffusion-v1-5 镜像部署:Web 界面与 Supervisor 自动恢复
  • 开源墙绘机:双轴张力控制低成本绘图系统
  • C++ 核心概念与面试知识点梳理
  • 常见 Web 漏洞渗透及防护方法
  • 基于 Python 与 Flask 的黑龙江旅游数据分析系统实战
  • 五分钟理解 Rust 核心概念:所有权
  • 绿联 NAS 配置 WebDAV 公网访问并使用 RaiDrive 挂载
  • 55 类空基算法开放接入,赋能无人机低空智能应用
  • AI 大模型从零到就业学习路径指南
  • AI 重构产品能力边界,让“人人都是产品经理”真正落地

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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