news 2026/4/8 4:11:41

后序遍历的递归算法核心思想是:按照“左子树 → 右子树 → 根节点”的顺序访问二叉树中的每个节点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
后序遍历的递归算法核心思想是:按照“左子树 → 右子树 → 根节点”的顺序访问二叉树中的每个节点

后序遍历的递归算法核心思想是:按照“左子树 → 右子树 → 根节点”的顺序访问二叉树中的每个节点。以下是完整的C语言实现示例:

#include<stdio.h>#include<stdlib.h>// 二叉树节点定义typedefstructTreeNode{intdata;structTreeNode*lchild;structTreeNode*rchild;}TreeNode;// 后序遍历递归实现voidPostOrder(TreeNode*root){if(root!=NULL){PostOrder(root->lchild);// 遍历左子树PostOrder(root->rchild);// 遍历右子树printf("%d ",root->data);// 访问根节点}}

关于三种遍历的路线逻辑,可以形象地理解为从根节点出发,沿二叉树外缘逆时针走一圈,每个节点会被经过三次:

  • 第一次经过时访问 → 先序遍历(根左右)
  • 第二次经过时访问 → 中序遍历(左根右)
  • 第三次经过时访问 → 后序遍历(左右根)

时间复杂度分析:
由于每个节点仅被访问一次,无论哪种遍历方式,总时间复杂度均为O(n)

空间复杂度分析:
主要消耗在系统调用栈上,取决于递归深度,即树的高度 h:

  • 平均情况(平衡树):O(log n)
  • 最坏情况(单枝树,退化为链表):O(n)

非递归遍历的基本思路是使用显式栈模拟函数调用栈的行为。以中序遍历为例,其非递归实现如下:

#include<stdbool.h>voidInOrderNonRecursive(TreeNode*root){TreeNode*stack[100];inttop=-1;TreeNode*p=root;while(p!=NULL||top!=-1){if(p!=NULL){stack[++top]=p;p=p->lchild;// 一直向左走}else{p=stack[top--];// 出栈printf("%d ",p->data);// 访问根p=p->rchild;// 转向右子树}}}

对于后序遍历的非递归实现,较为复杂,通常需要记录前驱节点或使用标志位来判断是否已遍历完左右子树。
实现二叉树的后序遍历非递归算法的关键在于:在不使用递归的情况下,正确判断何时访问根节点。由于后序遍历是“左→右→根”,我们必须确保在访问根节点前,其左右子树都已处理完毕。

常用方法是使用一个栈来保存待处理的节点,并借助一个指针记录上一次访问的节点(prev),从而判断当前节点是否可以被访问。

✅ 后序遍历非递归算法(单栈 + 标记法)

#include<stdio.h>#include<stdlib.h>typedefstructTreeNode{intdata;structTreeNode*lchild;structTreeNode*rchild;}TreeNode;voidPostOrderNonRecursive(TreeNode*root){if(root==NULL)return;TreeNode*stack[100];// 模拟栈inttop=-1;TreeNode*prev=NULL;// 记录上一次访问的节点TreeNode*curr=root;while(curr!=NULL||top!=-1){// 一直走到最左边if(curr!=NULL){stack[++top]=curr;curr=curr->lchild;}else{// 查看栈顶元素(不弹出)curr=stack[top];// 如果右子树为空或已被访问过,则可以访问当前节点if(curr->rchild==NULL||curr->rchild==prev){printf("%d ",curr->data);top--;// 弹出栈prev=curr;// 更新已访问节点curr=NULL;// 当前节点置空,避免重复入栈}else{// 否则转向右子树curr=curr->rchild;}}}}

🔍 算法逻辑说明:

  • 入栈顺序:从根开始一路向左,将路径上的所有节点入栈。
  • 判断访问时机
    • 若当前节点无右子树 → 可直接访问;
    • 或右子树已经被访问过(prev == curr->rchild)→ 表示左右子树均已处理,可访问根;
  • 否则:转向右子树继续处理。

🧪 示例:

对于如下二叉树:

1 / \ 2 3 / \ 4 5

后序遍历结果应为:4 5 2 3 1

该算法能正确输出此序列。


⏱️ 复杂度分析:

  • 时间复杂度:O(n),每个节点被压栈和弹栈一次。
  • 空间复杂度:O(h),h 为树的高度,最坏 O(n),平均 O(log n)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 13:10:48

YOLOv8类别不平衡问题缓解方法

YOLOv8类别不平衡问题缓解方法 在真实世界的目标检测任务中&#xff0c;模型常常面临一个看似简单却极具挑战性的问题&#xff1a;某些类别的目标几乎随处可见&#xff0c;而另一些则凤毛麟角。比如&#xff0c;在城市道路监控中&#xff0c;“汽车”可能每帧画面都出现几十次&…

作者头像 李华
网站建设 2026/3/24 17:03:37

YOLOv8自动学习超参数机制AUGMENTTrue说明

YOLOv8自动学习超参数机制AUGMENTTrue说明 在目标检测的实际项目中&#xff0c;一个常见的挑战是&#xff1a;如何用有限的数据训练出泛化能力强、鲁棒性高的模型&#xff1f;尤其是在工业质检、医疗影像或小样本场景下&#xff0c;数据稀缺问题尤为突出。传统做法依赖人工设计…

作者头像 李华
网站建设 2026/4/6 16:51:23

NunuAI:国内环境顶级模型平替

1. 放弃对单一模型的纯爱幻想 2025年底了&#xff0c;还在纠结 GPT-5.2 和 Claude-4.5 谁更强&#xff1f;这种争论在工程实践中毫无意义。现实情况是&#xff1a;OpenAI 的逻辑推演偶尔会陷入过度对齐的死循环&#xff0c;而 Anthropic 的模型在处理长文档关联时&#xff0c;…

作者头像 李华
网站建设 2026/3/23 9:03:36

YOLOv8预训练模型下载地址汇总(HuggingFace 官方)

YOLOv8预训练模型下载地址汇总&#xff08;HuggingFace & 官方&#xff09; 在智能安防、工业质检和自动驾驶等实时视觉系统中&#xff0c;开发者常常面临一个看似简单却极易卡壳的问题&#xff1a;如何快速获取可运行的YOLOv8预训练模型&#xff1f;不是每个人都有时间从…

作者头像 李华
网站建设 2026/3/31 1:29:42

论文降AI率之前,这些句式不改基本必翻

一、为什么手动降重总翻车&#xff1f;学术党必知的3大痛点“明明查重率达标了&#xff0c;导师却说论文有AI味要求重写&#xff01;”——这是不是你的真实写照&#xff1f;很多同学误以为同义词替换调整句式就能蒙混过关&#xff0c;结果陷入三大困局&#xff1a;❌ 痛点1&am…

作者头像 李华
网站建设 2026/3/23 9:03:33

降 AI 率这件事,其实有固定思路

一、为什么手动降重总翻车&#xff1f;学术党必知的3大痛点“明明查重率达标了&#xff0c;导师却说论文有AI味要求重写&#xff01;”——这是不是你的真实写照&#xff1f;很多同学误以为同义词替换调整句式就能蒙混过关&#xff0c;结果陷入三大困局&#xff1a;❌ 痛点1&am…

作者头像 李华