news 2026/4/15 15:23:17

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

作者头像

张小明

前端开发工程师

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/14 23:11:56

线索二叉树是对普通二叉树的优化结构,旨在提高遍历效率

一、线索二叉树 线索二叉树是对普通二叉树的优化结构&#xff0c;旨在提高遍历效率。在传统二叉树中&#xff0c;每个结点有左右两个指针&#xff0c;对于n个结点的二叉树&#xff0c;共有2n个指针域&#xff0c;其中只有n-1个被用于连接子结点&#xff0c;其余n1个为空。线索二…

作者头像 李华
网站建设 2026/4/15 11:31:00

GPT-5.2与Claude-4.5国内直连实操指南

2025年最后一天&#xff0c;如果你还在折腾网络或者买那种随时会封号的海外代充&#xff0c;或者忍受镜像站背后偷偷换成低版本API的降智服务&#xff0c;那你这几年的技术圈真是白混了。在当前GPT-5.2和Claude-4.5满地走的环境中&#xff0c;稳定直连和白嫖额度才是硬道理。 …

作者头像 李华
网站建设 2026/4/15 8:10:42

互联网大厂Java面试实录:从Spring到微服务的全面探索

互联网大厂Java面试实录&#xff1a;从Spring到微服务的全面探索 场景描述&#xff1a; 在一家知名互联网大厂的面试室里&#xff0c;面试官严肃地坐在桌子的一边&#xff0c;他面前坐着一位初入职场的Java小白程序员&#xff0c;名叫超好吃。今天的面试主题围绕Java核心技术栈…

作者头像 李华
网站建设 2026/4/10 23:14:54

大模型如何评测之——“刻意破坏训练中的高频共现统计“模板

1、评测样本模板模板 → 示例 → 测什么 → 常见失败&#xff0c;建评测集。一、语言形式 能力解耦类模板 1&#xff1a;低语言质量 高专业度模板【非标准/口语/有错别字的表达】【本质是专业/技术/学术问题】示例“我这个最小二成回归哈&#xff0c; 就是残插不是正太分布会…

作者头像 李华
网站建设 2026/4/6 9:14:49

YOLOv8预测置信度阈值设置技巧

YOLOv8预测置信度阈值设置技巧 在智能监控系统部署过程中&#xff0c;一个常见的问题是&#xff1a;明明模型在测试集上表现优异&#xff0c;实际运行时却频繁误报或漏检。比如夜间摄像头将路灯反光识别为车辆&#xff0c;或者远处的行人因尺寸过小而被完全忽略——这些问题背后…

作者头像 李华
网站建设 2026/4/15 6:21:38

多元统计分析不会做?R语言带你玩转生态数据,快速出图出结果

第一章&#xff1a;R 语言 多元统计分析 生态数据在生态学研究中&#xff0c;多元统计分析是探索物种分布、环境因子影响以及群落结构变化的重要工具。R 语言凭借其强大的统计计算能力和丰富的生态学相关包&#xff08;如 vegan、ade4、labdsv&#xff09;&#xff0c;成为处理…

作者头像 李华