【数据结构】树与二叉树(十):二叉树的先序遍历(非递归算法NPO)

文章目录

5.2.1 二叉树

  二叉树是一种常见的树状数据结构,它由结点的有限集合组成。一个二叉树要么是空集,被称为空二叉树,要么由一个根结点和两棵不相交的子树组成,分别称为左子树右子树。每个结点最多有两个子结点,分别称为左子结点和右子结点。
在这里插入图片描述

二叉树性质

引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i0

引理5.2:高度为k的二叉树中至多有 2 k + 1 − 1 2^{k+1}-1 2k+11个结点,其中 k ≥ 0 k \geq 0 k0

引理5.3:设T是由n个结点构成的二叉树,其中叶结点个数为 n 0 n_0 n0,度数为2的结点个数为 n 2 n_2 n2,则有 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1

  • 详细证明过程见前文:【数据结构】树与二叉树(三):二叉树的定义、特点、性质及相关证明

满二叉树、完全二叉树定义、特点及相关证明

  • 详细证明过程见前文:【数据结构】树与二叉树(四):满二叉树、完全二叉树及其性质

5.2.2 二叉树顺序存储

  二叉树的顺序存储是指将二叉树中所有结点按层次顺序存放在一块地址连续的存储空间中,详见:
【数据结构】树与二叉树(五):二叉树的顺序存储(初始化,插入结点,获取父节点、左右子节点等)

5.2.3 二叉树链接存储

  二叉树的链接存储系指二叉树诸结点被随机存放在内存空间中,结点之间的关系用指针说明。在链式存储中,每个二叉树结点都包含三个域:数据域(Data)、左指针域(Left)和右指针域(Right),用于存储结点的信息和指向子结点的指针,详见:
【数据结构】树与二叉树(六):二叉树的链式存储

5.2.4 二叉树的遍历

  • 遍历(Traversal)是对二叉树中所有节点按照一定顺序进行访问的过程。
  • 通过遍历,可以访问树中的每个节点,并按照特定的顺序对它们进行处理。
  • 对二叉树的一次完整遍历,可给出树中结点的一种线性排序。
    • 在二叉树中,常用的遍历方式有三种:先序遍历中序遍历后序遍历
    • 这三种遍历方式都可以递归地进行,它们的区别在于节点的访问顺序
      • 在实现遍历算法时,需要考虑递归终止条件和递归调用的顺序。
    • 还可以使用迭代的方式来实现遍历算法,使用栈或队列等数据结构来辅助实现。
  • 遍历是二叉树中基础而重要的操作,它为其他许多操作提供了基础,如搜索、插入、删除等。
    在这里插入图片描述

1-3 先序、中序、后序遍历递归实现及相关练习

【数据结构】树与二叉树(七):二叉树的遍历(先序、中序、后序及其C语言实现)

后序遍历递归实现

void postOrderTraversal(struct Node* root) {if (root == NULL) {return;}// 递归遍历左子树postOrderTraversal(root->left);// 递归遍历右子树postOrderTraversal(root->right);// 访问根节点printf("%c ", root->data);
}

4. 中序遍历非递归

【数据结构】树与二叉树(八):二叉树的中序遍历(非递归算法NIO)

5. 后序遍历非递归

【数据结构】树与二叉树(九):二叉树的后序遍历(非递归算法NPO)

6. 先序遍历非递归

a. 算法NPO

在这里插入图片描述
说明:该ADL语言算法流程为本人所写,不具备权威性,如有错误望忽视,请跳转至下文具体C语言实现部分。

b. 算法解读

  算法NPO(t)利用了一个辅助堆栈S来遍历二叉树T的所有节点。

  1. 如果根节点t为空,则直接返回。
  2. 创建一个空堆栈S,并将根节点t和初始标记0入栈(S <= (t, 0))。
  3. 进入循环,只要堆栈S非空,执行以下步骤:
    a. 从堆栈S中弹出栈顶元素,将其赋值给(p, i)。
    b. 如果标记i为0,则表示节点p还未处理,打印节点p的值,并将左子节点入栈(S <= (Left§, 0)),然后将标记置为1(S <= (p, 1))。
    c. 如果标记i为1,则表示节点p的左子树已处理完毕,将右子节点入栈(S <= (Right§, 0)),然后将标记置为2(S <= (p, 2))。
    d. 如果标记i为2,则表示节点p的左右子树都已处理完毕,将节点p从堆栈S中弹出(S.pop())。
  4. 跳转到步骤3,继续循环,直到堆栈S为空。

c. 复杂度分析

  设二叉树有n个结点。算法NPO中,每个结点的状态都是从0→1→2,每个状态都要经历1次入栈和1次出栈,即入栈和出栈各执行3n次,另外,每个结点都进行1次访问,即访问还要执行n次,因此,算法NPO的时间复杂度为O(n).

d.代码实现

void nonRecursiveInOrder(struct Node* root) {struct Node* stack[100];  // 辅助堆栈,用于模拟递归调用栈int top = -1;  // 栈顶指针struct Node* current = root;while (current != NULL || top != -1) {// 将当前结点的左子结点入栈while (current != NULL) {stack[++top] = current;current = current->left;}// 弹出栈顶结点,并访问current = stack[top--];printf("%c ", current->data);// 处理右子结点current = current->right;}
}

5. 代码整合

#include <stdio.h>
#include <stdlib.h>// 二叉树结点的定义
struct Node {char data;struct Node* left;struct Node* right;
};// 创建新结点
struct Node* createNode(char data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));if (newNode == NULL) {printf("Memory allocation failed!\n");exit(1);}newNode->data = data;newNode->left = NULL;newNode->right = NULL;return newNode;
}// 先序遍历
void PreOrderTraversal(struct Node* root) {if (root == NULL) {return;}// 访问根节点printf("%c ", root->data);// 递归遍历左子树PreOrderTraversal(root->left);// 递归遍历右子树PreOrderTraversal(root->right);}// 非递归先序遍历
void nonRecursivePreOrder(struct Node* root) {if (root == NULL) {return;}struct Node* stack[100];  // 辅助堆栈,用于模拟递归调用栈int top = -1;  // 栈顶指针stack[++top] = root;while (top != -1) {struct Node* current = stack[top--];printf("%c ", current->data);if (current->right != NULL) {stack[++top] = current->right;}if (current->left != NULL) {stack[++top] = current->left;}}
}int main() {// 创建一棵二叉树struct Node* root = createNode('a');root->left = createNode('b');root->right = createNode('c');root->left->left = createNode('d');root->left->right = createNode('e');root->left->right->left = createNode('f');root->left->right->right = createNode('g');// 递归先序序遍历二叉树printf("Recursive Pre-order traversal: \n");PreOrderTraversal(root);printf("\n");// 非递归先序遍历二叉树printf("Non-recursivePre-order traversal: \n");nonRecursivePreOrder(root);printf("\n");return 0;
}

在这里插入图片描述

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

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

相关文章

Python实战:绘制直方图的示例代码,数据可视化获取样本分布特征

文章目录 一、初步二、参数三、绘图类型四、多组数据直方图对比Python技术资源分享1、Python所有方向的学习路线2、学习软件3、精品书籍4、入门学习视频5、实战案例6、清华编程大佬出品《漫画看学Python》7、Python副业兼职与全职路线 一、初步 对于大量样本来说&#xff0c;如…

2023年【危险化学品经营单位主要负责人】免费试题及危险化学品经营单位主要负责人证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品经营单位主要负责人免费试题为正在备考危险化学品经营单位主要负责人操作证的学员准备的理论考试专题&#xff0c;每个月更新的危险化学品经营单位主要负责人证考试祝您顺利通过危险化学品经营单位主…

前端开发学习指南

前端是一个看似入门门槛不高&#xff0c;但要学好很难的领域。前端的知识体系庞杂又松散&#xff0c;技术演进快&#xff0c;如果摸不清脉络的话很容易陷入盲人摸象的困境甚至跑偏。 其实只要掌握了正确的方法&#xff0c;学习前端和学好前端就只是个时间问题&#xff0c;希望下…

OpenCV图像坐标系

绘制代码: X轴 # 选取两个点 point1 = (20, 0) point2 = (200, 0)# 在图像上绘制连接线 cv2.line(img, point1, point2, (

解决找不到x3daudio1_7.dll的方法,快速解决x3daudio1_7.dll丢失问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到x3daudio1_7.dll”。这个问题可能是由于多种原因引起的&#xff0c;例如文件丢失、损坏或被病毒感染等。下面将详细介绍如何解决这个问题。 首先&#xff0c;我们需要了解x3daudio1_…

Kotlin HashMap entries.filter过滤forEach

Kotlin HashMap entries.filter过滤forEach fun main(args: Array<String>) {val hashMap HashMap<String, Int>()hashMap["a"] 1hashMap["b"] 2hashMap["c"] 3println(hashMap)hashMap.entries.filter {println("filter $…

2023年【北京市安全员-C3证】考试题库及北京市安全员-C3证在线考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-C3证考试题库是安全生产模拟考试一点通总题库中生成的一套北京市安全员-C3证在线考试&#xff0c;安全生产模拟考试一点通上北京市安全员-C3证作业手机同步练习。2023年【北京市安全员-C3证】考试题库及…

Nignx及负载均衡动静分离

目录 一.Nginx负载均衡 1.1.下载 1.2.安装 1.3.负载均衡 二.前端部署 2.1. 准备工作 2.2.部署 好啦今天就到这里了哦&#xff01;&#xff01;&#xff01;希望能帮到你哦&#xff01;&#xff01;&#xff01; 一.Nginx负载均衡 1.1.下载 输入命令 : cd javaCloudJun/…

键盘win键无法使用,win+r不生效、win键没反应、Windows键失灵解决方案(亲测可以解决)

最近几天发现自己笔记本的win键无法使用&#xff0c;win失灵了&#xff0c;但是外接键盘后则正常:。 这个问题困扰了我一周&#xff0c;我都以为自己的枪神坏了。 寻找了几个解决方法&#xff0c;网上看了好多好多稀里糊涂的办法&#xff0c;都是不管用的&#xff0c;这里给大…

超简单的Linux FTP服务搭建教程

目录 前言1、检查vsftp是否已安装2、安装vsftpd3、启动ftp服务4、测试ftp服务5、上传文件配置总结 前言 本文记录了在Kylin Linux Desktop V10(SP1)系统上搭建FTP服务的过程。FTP是File Transfer Protocol的缩写&#xff0c;译为文件传输协议&#xff0c;是用于在网络上进行文…

向量的点积和外积

参考&#xff1a;https://www.cnblogs.com/gxcdream/p/7597865.html 一、向量的内积&#xff08;点乘&#xff09; 定义&#xff1a; 两个向量a与b的内积为 ab |a||b|cos∠(a, b)&#xff0c;特别地&#xff0c;0a a0 0&#xff1b;若a&#xff0c;b是非零向量&#xff0c;…

【读点论文】结构化剪枝

结构化剪枝 在一个神经网络模型中&#xff0c;通常包含卷积层、汇合层、全连接层、非线形层等基本结构&#xff0c;通过这些基本结构的堆叠&#xff0c;最终形成我们所常用的深度神经网络。 早在 1998 年&#xff0c;LeCun 等人使用少数几个基本结构组成 5 层的 LeNet-5 网络&…

GitHub Copilot Chat将于12月全面推出;DeepLearning.AI免费新课

&#x1f989; AI新闻 &#x1f680; GitHub Copilot Chat将于12月全面推出&#xff0c;提升开发者的生产力 摘要&#xff1a;GitHub宣布将于12月全面推出GitHub Copilot Chat&#xff0c;这是GitHub Copilot的一个新功能&#xff0c;旨在帮助开发者编写代码。它能够集成到开…

解决Docker启动之npm版本不兼容问题

报错内容&#xff1a; npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion1, but package-lock.json was generated for lockfileVersion2. Ill try to do my best with it! npm WARN tar ENOENT: no such file or directory, open /home/wvp-…

一个轻量级 Java 权限认证框架——Sa-Token

一、框架介绍 Sa-Token 是一个轻量级 Java 权限认证框架&#xff0c;主要解决&#xff1a;登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。 官网文档: https://sa-token.cc/doc.html 二、Spring Boot 集成Sa-Token 2.1、…

【机器学习】七、降维与度量学习

1. 维数灾难 样本的特征数称为维数&#xff08;dimensionality&#xff09;&#xff0c;当维数非常大时&#xff0c;也就是现在所说的维数灾难。 维数灾难具体表现在&#xff1a;在高维情形下&#xff0c;数据样本将变得十分稀疏&#xff0c;因为此时要满足训练样本为“密采样…

函数的连续性

函数在某一点极限存在&#xff0c;不一定连续 函数的左极限 函数的右极限 函数在某点连续需要满足三个条件 1、左右极限存在 2、左右极限相等 3、函数在该点的极限值等于在该点的函数值 满足1、2两个条件函数在该点极限存在。

kubernetes集群编排——k8s调度

nodename vim nodename.yaml apiVersion: v1 kind: Pod metadata:name: nginxlabels:app: nginxspec:containers:- name: nginximage: nginxnodeName: k8s2 nodeName: k8s2 #找不到节点pod会出现pending&#xff0c;优先级最高 kubectl apply -f nodename.yamlkubectl get pod …

【Node.js入门】1.2 部署Node.js开发环境

1.2 部署Node.js开发环境 在 Windows 系统上安装 Node.js 两种文件格式的安装包 Windows安装包&#xff08;.msi&#xff09;Windows二进制文件&#xff08;.exe&#xff09;安装包 检查Node.js版本 node --version 在 Linux 系统上安装 Node.js Linux操作系统上安装Nod…

深度学习 python opencv 动物识别与检测 计算机竞赛

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…