【数据结构与算法】二叉树前序,中序,后序遍历非递归版。Leetcode接口

144. 二叉树的前序遍历 - 力扣(LeetCode)

  1. 如果根节点为空,直接返回。
  2. 初始化一个辅助栈 s,并将根节点入栈。
  3. 重复以下步骤,直到栈为空:
    • 检查当前节点 tmp
      • 如果 tmp 不为空:
        • 将当前节点 tmp 入栈,并将节点值 tmp->val 添加到结果数组 a 中。
        • 将当前节点的左子节点赋值给 tmp,继续进行下一轮循环。
      • 如果当前节点 tmp 为空:
        • 获取栈顶节点的右子节点赋值给 tmp
        • 弹出栈顶节点。
  4. 遍历结束后,结果数组 a 中存储的就是二叉树前序遍历的结果。
typedef struct TreeNode* DataType;
typedef struct StackNode
{DataType data;struct StackNode* next;
}StackNode;
typedef struct Stack
{StackNode* top;
}Stack;void StackInit(Stack* s)
{s->top = NULL;
}int StackEmpty(Stack* s)
{return s->top == NULL;
}void StackPush(Stack* s, DataType x)
{StackNode* tmp = (StackNode*)malloc(sizeof(StackNode));tmp->data = x;tmp->next = NULL;if(s->top == NULL){s->top = tmp;}else{tmp->next = s->top;s->top = tmp;}
}DataType StackTop(Stack* s)
{if(!StackEmpty(s)){return s->top->data;}return NULL;
}void StackPop(Stack* s)
{if(!StackEmpty(s)){StackNode* tmp = s->top;s->top = s->top->next;free(tmp);}else{exit(-1);}
}
int TreeSize(struct TreeNode* root) {return root == NULL ? 0 : 1 + TreeSize(root->left) + TreeSize(root->right);
}void pre_order(struct TreeNode* root, int* a, int* i) {if(root==NULL){return;}Stack s;StackInit(&s);struct TreeNode* tmp = root;while(tmp || !StackEmpty(&s)){if(tmp){StackPush(&s,tmp);a[(*i)++] = tmp -> val;tmp = tmp -> left;}else{tmp = StackTop(&s) -> right;StackPop(&s);}}
}int* preorderTraversal(struct TreeNode* root, int* returnSize) {int n = TreeSize(root);*returnSize = n;int* a = (int*)malloc(sizeof(int) * n);int i = 0;pre_order(root, a, &i);return a;
}

94. 二叉树的中序遍历 - 力扣(LeetCode)

首先创建一个空的栈 s,再用一个临时指针 tmp 指向根节点 root

然后进行循环,直到 tmp 指针为空且栈为空。在循环中,如果 tmp 指针不为空,则将 tmp 入栈,并将 tmp 移动到其左子树。

如果 tmp 指针为空,则表示已经到达最左边的叶子节点,此时将栈顶节点出栈,将节点的值存入数组 a 中,并将 tmp 指向该节点的右子树。 

typedef struct TreeNode* DataType;
typedef struct StackNode
{DataType data;struct StackNode* next;
}StackNode;
typedef struct Stack
{StackNode* top;
}Stack;void StackInit(Stack* s)
{s->top = NULL;
}int StackEmpty(Stack* s)
{return s->top == NULL;
}void StackPush(Stack* s, DataType x)
{StackNode* tmp = (StackNode*)malloc(sizeof(StackNode));tmp->data = x;tmp->next = NULL;if(s->top == NULL){s->top = tmp;}else{tmp->next = s->top;s->top = tmp;}
}DataType StackTop(Stack* s)
{if(!StackEmpty(s)){return s->top->data;}return NULL;
}void StackPop(Stack* s)
{if(!StackEmpty(s)){StackNode* tmp = s->top;s->top = s->top->next;free(tmp);}else{exit(-1);}
}void inorder(struct TreeNode* root,int **a,int *pi)
{if(root==NULL){return;}Stack s;StackInit(&s);struct TreeNode* tmp = root;while(tmp || !StackEmpty(&s)){if(tmp){StackPush(&s, tmp);tmp=tmp->left;}else{tmp = StackTop(&s);(*a)[(*pi)++] = tmp->val;StackPop(&s);tmp = tmp->right;}}
}int treesize(struct TreeNode* root)
{if(root==NULL){return 0;}return 1+treesize(root->left)+treesize(root->right);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {int count=treesize(root);int *a=(int*)malloc(count*sizeof(int));int pi=0;inorder(root,&a,&pi);*returnSize=pi;return a;
}

145. 二叉树的后序遍历 - 力扣(LeetCode)

具体的逻辑如下:

  1. 如果根节点为空,直接返回。
  2. 初始化一个辅助栈 stack,并将根节点入栈。
  3. 重复以下步骤,直到栈为空:
    • 将当前节点及其左子节点依次入栈,直到当前节点的左子节点为空。
    • 检查当前栈顶节点的右子节点:
      • 如果右子节点为空或者已经访问过(即和 prev 指向的节点相同),说明当前节点的右子树已经处理完毕,将栈顶节点弹出,并将节点值添加到结果数组中。
      • 否则,继续处理右子节点,将右子节点赋值给当前节点,并进行下一轮循环。
    • 更新 prev 指向当前处理的节点。
  4. 遍历结束后,结果数组中存储的就是二叉树后序遍历的结果。
typedef struct TreeNode* DataType;
typedef struct StackNode
{DataType data;struct StackNode* next;
}StackNode;
typedef struct Stack
{StackNode* top;
}Stack;void StackInit(Stack* s)
{s->top = NULL;
}int StackEmpty(Stack* s)
{return s->top == NULL;
}void StackPush(Stack* s, DataType x)
{StackNode* tmp = (StackNode*)malloc(sizeof(StackNode));tmp->data = x;tmp->next = NULL;if(s->top == NULL){s->top = tmp;}else{tmp->next = s->top;s->top = tmp;}
}DataType StackTop(Stack* s)
{if(!StackEmpty(s)){return s->top->data;}return NULL;
}void StackPop(Stack* s)
{if(!StackEmpty(s)){StackNode* tmp = s->top;s->top = s->top->next;free(tmp);}else{exit(-1);}
}
void postorder(struct TreeNode* root, int **a, int *pi) {if (root == NULL) {return;}struct TreeNode* prev = NULL;Stack stack;StackInit(&stack);struct TreeNode* current = root;while (current != NULL || !StackEmpty(&stack)) {// 将当前节点及其左子节点依次入栈while (current != NULL) {StackPush(&stack, current);current = current->left;}// 检查当前栈顶节点的右子节点// 如果右子节点为空或者已经访问过,则将栈顶节点弹出并添加到结果数组中if (StackTop(&stack)->right == NULL || StackTop(&stack)->right == prev) {struct TreeNode* node = StackTop(&stack);StackPop(&stack);(*a)[(*pi)++] = node->val;  // 将节点值添加到结果数组prev = node;  // 更新上一个访问的节点} else {// 处理右子节点current = StackTop(&stack)->right;}}
}
int treesize(struct TreeNode* root)
{if(root==NULL){return 0;}return 1+treesize(root->left)+treesize(root->right);
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {int count=treesize(root);int *a=(int*)malloc(count*sizeof(int));int pi=0;postorder(root,&a,&pi);*returnSize=pi;return a;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/665158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

寒假作业-day2

进程间通信的7种方式,总结出他们的优点 1. 内核提供的原始通信方式有三种 1.1 无名管道 1.2 有名管道 1.3 信号 2. System V提供了三种通信方式 2.1 消息队列 2.2 共享内存 3.1 信号量(信号灯集) 3. 套接字通信:socket …

十一、计算机分类

1、按照性能和用途分类 计算机分类 计算机按照性能、用途和规模可以分为以下几种类型: 1)巨型机(超级计算机) 采用大规模并行处理体系结构。运算速度最快、体积最大、价格最昂贵。主要用于尖端科学研究领域,如灾难预测…

《计算机网络简易速速上手小册》第2章:计算机网络协议和标准(2024 最新版)

文章目录 2.1 IPv4 与 IPv6 - 网络世界的地址簿2.1.1 基础知识2.1.2 重点案例:使用 Python 查询本机 IPv4 和 IPv6 地址2.1.3 拓展案例1:使用 Python 创建简单的 IP 地址转换工具2.1.4 拓展案例2:使用 Python 检测本地网络的 IP 版本支持 2.2…

前端学习02

1.CSS案例 1.1 内容回顾 1.1.1 搭建骨架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>body{margin: 0;}.sub-header{height: 100px;background-color: #b0b0b0…

js中常用数组去重方法

js中常用去重方法 一、使用 Set ES6 提供了 Set 类型&#xff0c;它可以自动去重 const arr [1, 2, 2, 3, 3, 4]; const newArr Array.from(new Set(arr)); console.log(newArr ); // [1, 2, 3, 4]二、使用 filter 方法 const arr [1, 2, 2, 3, 3, 4]; const newArr ar…

unity 导出H5

Unity 输出html5_mob649e8157aaee的技术博客_51CTO博客 Unity打包WebGL报Unable to parse Build/*.framework.js.gz This can happen if build compression was......._unable to load file build/out.framework.js.gz! che-CSDN博客

ES6-对象的解构赋值

一、区别一下数组的解构赋值 - 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的&#xff0c;变量的取值由它的位置决定&#xff1b;而对象的属性没有次序&#xff0c;变量必须与属性同名&#xff0c;才能取到正确的值二、说明 - 对象的解构赋值的内部机制&#…

【Vitis】Vitis HLS学习系列笔记 :第一个例程

在学习vitis的过程中一定要跑几个例程试试看&#xff0c;这中间遇到了几个小问题&#xff0c;记录下 有干货&#xff0c;请注意查收&#xff1a;作为新手&#xff0c;跑例程大概率会遇到问题&#xff0c;这里记录几个问题&#xff0c;如果刚好你也遇到&#xff0c;一定会帮到你…

XML详解

文章目录 XML简介语法约束DTDSchema 解析Jsoup使用对象详解JsoupDocumentElementsElementNode XML 简介 概述&#xff1a;Extensible Markup Language 可扩展标记语言 可扩展&#xff1a;标签都是自定义的。 功能 数据存储&#xff1a;XML 可以用来存储结构化数据&#xff0c…

HSRP配置指南

实验大纲 第 1 部分&#xff1a;验证连通性 步骤 1&#xff1a;追踪从 PC-A 到 Web 服务器的路径 步骤 2&#xff1a;追踪从 PC-B 到 Web 服务器的路径 步骤 3&#xff1a;观察当 R3 不可用时&#xff0c;网络的行为 第 2 部分&#xff1a;配置 HSRP 主用和 备用路由器 步…

rasa3.X 自定义action的注册问题

rasa3.X 自定义action的注册问题 文章目录 rasa3.X 自定义action的注册问题前言一、问题重述二、问题解决 前言 幸好在这之前抽时间稍微看了一点django源码&#xff0c;让我对于python的导入机制有了一个概念。虽然还不是很确切的知道python import机制&#xff0c;不过在看到…

QT学习日记 | 初始QT

目录 一、创建QT文件 二、目录结构讲解 1、.pro文件 2、源文件与头文件 3、编译运行 4、界面文件 三、梦开始的地方&#xff08;Hello World&#xff01;&#xff09; 1、代码方式 2、拖拽方式 四、Qt中的“容器” 五、Qt的对象树机制 1、对象树的引入 2、对象树…

MySQL进阶之锁(全局锁以及备份报错解决)

锁 全局锁 全局锁就是对整个数据库实例加锁&#xff0c;加锁后整个实例就处于只读状态&#xff0c;后续的DML的写语句&#xff0c;DDL语 句&#xff0c;已经更新操作的事务提交语句都将被阻塞。 其典型的使用场景是做全库的逻辑备份&#xff0c;对所有的表进行锁定&#xff…

030-安全开发-JS应用NodeJS指南原型链污染Express框架功能实现审计

030-安全开发-JS应用&NodeJS指南&原型链污染&Express框架&功能实现&审计 #知识点&#xff1a; 1、NodeJS-开发环境&功能实现 2、NodeJS-安全漏洞&案例分析 3、NodeJS-开发指南&特有漏洞 演示案例&#xff1a; ➢环境搭建-NodeJS-解析安装&…

MySQL知识点总结(三)——事务

MySQL知识点总结&#xff08;三&#xff09;——事务 事务事务的四大特性ACID原子性一致性隔离性持久性 脏读、幻读、不可重复读脏读不可重复读幻读 隔离级别读未提交读已提交可重复读串行化 事务的原理InnoDB如何实现事务的ACID事务的两阶段提交redo log与binlog的区别事务两阶…

【DevOps】产品需求文档(PRD)与常见原型软件

文章目录 1、PRD介绍1.1、概述1.2、前提条件1.3、主要目的1.4、关键内容1.5、表述方式1.6、需求评审人员1.7、一般内容结构 2、需求流程3、常见原型软件3.1、Word3.2、Axure3.2.1、详细介绍3.2.2、应用分类3.2.3、优缺点 3.3、摹客RP3.4、蓝湖3.5、GUI Design Studio 1、PRD介绍…

业务流程自动化平台在制造业应用案例,助力业务自动化、智能化

捷昌驱动成立于2000年&#xff0c;并于2018年9月在上海证券交易所上市&#xff0c;是一家专注于线性驱动产品研发、生产及销售的科技集团。 公司整合全球资源&#xff0c;为智慧办公、医疗康护、智能家居、工业自动化等关联产业提供驱动及智能控制解决方案&#xff0c;以科技驱…

C# 浅克隆与深克隆

在C#中&#xff0c;浅克隆&#xff08;Shallow Clone&#xff09;和深克隆&#xff08;Deep Clone&#xff09;是两种常见的对象克隆技术&#xff0c;用于创建对象的新副本。 它们的主要区别在于复制对象的层次和属性的处理方式。 浅克隆&#xff08;Shallow Copy&#xff09;…

荣耀手机如何录屏?在线分享3个录屏方法

荣耀手机如何录屏&#xff1f;荣耀手机录屏是一项非常实用的功能&#xff0c;它可以帮助我们轻松记录手机屏幕上的内容&#xff0c;无论是游戏攻略、教育学习还是工作演示&#xff0c;都能够方便地进行录制。通过录屏&#xff0c;我们可以随时随地记录和分享自己的操作和见解。…

探究Steam爆款游戏”幻兽帕鲁“:玩家评价揭秘

探究Steam爆款游戏”幻兽帕鲁“&#xff1a;玩家评价揭秘 文章目录 探究Steam爆款游戏”幻兽帕鲁“&#xff1a;玩家评价揭秘1 背景描述2 数据说明3 数据来源4 问题描述5 数据探索与预处理5.1 数据加载5.2 数据清洗 6 数据分析6.1 评论分布分析6.2 评论内容情感分析6.3 地理分布…