C/C++ 每日一练:二叉树的先序遍历

二叉树 binary tree

定义

        二叉树是一种树状数据结构,非线性数据结构,代表“祖先”与“后代”之间的派生关系,体现了“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,二叉树的每个节点包含三个主要部分:

  • 节点值:存储该节点的数据。
  • 左子节点(left-child node):指向该节点左侧的子树或为空。
  • 右子节点(right-child node):指向该节点右侧的子树或为空。

        二叉树节点结构体如下所示:

/* 二叉树节点结构体 */
struct TreeNode {int val;          // 节点值TreeNode *left;   // 左子节点指针TreeNode *right;  // 右子节点指针TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

        当给定一个二叉树的节点时,将该节点的左子节点及其以下节点形成的树称为该节点的 左子树(left subtree),同理可得 右子树(right subtree)

        举个例子,下面是一棵简单的二叉树:

        在这棵二叉树中:

  • 节点 1 是根节点,它有两个子节点 2 和 3。
  • 节点 2 是节点 1 的左子节点,它有两个子节点 4 和 5。
  • 节点 3 是节点 1 的右子节点,且没有子节点。
  • 节点 4 和节点 5 没有子节点,称为叶节点

        在二叉树中,除叶节点外,其他所有节点都包含子节点和非空子树。如上图所示,如果将“节点 2”视为父节点,则其左子节点和右子节点分别是“节点 4”和“节点 5”,左子树是“节点 4 及其以下节点形成的树”,右子树是“节点 5 及其以下节点形成的树”。

 常见术语

        二叉树的常用术语如图所示:

  •  根节点 root node :位于二叉树顶层的节点,没有父节点。
  •  叶节点 leaf node :没有子节点的节点,其两个指针均指向 None 。
  •  边 edge :连接两个节点的线段,即节点引用(指针)。
  • 节点所在的 层 level :从顶至底递增,根节点所在层为 1 。
  • 节点的 度 degree :节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2 。
  • 二叉树的 高度 height  :从根节点到最远叶节点所经过的边的数量。
  • 节点的 深度 depth :从根节点到该节点所经过的边的数量。
  • 节点的 高度 height :从距离该节点最远的叶节点到该节点所经过的边的数量。


二叉树的先序遍历

        二叉树的遍历方式主要有以下几种:

  • 先序遍历(Preorder Traversal):根节点 -> 左子树 -> 右子树。
  • 中序遍历(Inorder Traversal):左子树 -> 根节点 -> 右子树。
  • 后序遍历(Postorder Traversal):左子树 -> 右子树 -> 根节点。
  • 层次遍历(Level Order Traversal):按照树的层级逐层访问节点。

        先序遍历是一种访问二叉树节点的顺序,按如下规则遍历每个节点:

  1. 首先访问根节点。
  2. 递归地先序遍历根节点的左子树。
  3. 然后递归地先序遍历根节点的右子树。

        举个例子,下面是一棵简单的二叉树:

        1/ \2   3/ \4   5

         遍历顺序为:1 -> 2 -> 4 -> 5 -> 3

  1. 访问根节点 1
  2. 递归遍历左子树,访问 2,再递归到左子树访问 44没有子节点返回上一层。
  3. 回到节点 2,然后访问 55没有子节点返回。
  4. 左子树遍历完成,回到根节点 1,接着访问右子树节点 3

题目要求

         给定一个二叉树的根节点,编写程序实现先序遍历并打印每个节点的值。要求如下:

  • 请实现递归和非递归(使用栈)两种方法(本文中,C使用递归方法,C++使用非递归)。
  • 输出每个节点的值。

做题思路

         先序遍历是一种从根节点开始,依次遍历左子树和右子树的树遍历方法。可以用递归和迭代来实现:

  • 递归方法:根据先序遍历的定义,先访问当前节点,然后递归地访问左子树和右子树。
  • 非递归方法:使用栈来模拟递归过程。先将根节点压入栈中,之后在每次迭代中取出栈顶节点并访问其值,接着将右子节点和左子节点分别入栈(保证左节点先出栈)。

运用到的知识点

  • 递归:函数调用自身以简化复杂问题,是二叉树遍历的典型方法。
  • 栈(Stack):一种后进先出的数据结构,用于实现非递归的先序遍历。
  • 二叉树数据结构:二叉树中每个节点最多有两个子节点,即左子节点和右子节点。

示例代码

C 实现(递归实现)

#include <stdio.h> // 引入标准输入输出库,用于printf函数  
#include <stdlib.h> // 引入标准库,用于malloc函数  // 定义二叉树节点结构体  
struct TreeNode {  int val; // 节点的值  struct TreeNode *left; // 指向左子节点的指针  struct TreeNode *right; // 指向右子节点的指针  
};  // 创建新节点的函数  
// 参数:val - 新节点的值  
// 返回值:指向新创建的节点的指针  
struct TreeNode* createNode(int val) {  struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode)); // 分配内存给新节点  node->val = val; // 设置节点的值  node->left = NULL; // 初始化左子节点指针为空  node->right = NULL; // 初始化右子节点指针为空  return node; // 返回新节点的指针  
}  // 先序遍历递归函数  
// 参数:root - 要遍历的二叉树的根节点  
void preorderTraversal(struct TreeNode* root) {  if (root == NULL) return; // 如果当前节点为空,则直接返回,不继续遍历  // 访问根节点  printf("%d ", root->val); // 打印当前节点的值  // 递归遍历左子树  preorderTraversal(root->left); // 递归调用先序遍历函数,遍历左子树  // 递归遍历右子树  preorderTraversal(root->right); // 递归调用先序遍历函数,遍历右子树  
}  int main() 
{  // 构建示例二叉树  // 创建根节点  struct TreeNode* root = createNode(1);  // 创建左子节点,并连接到根节点  root->left = createNode(2);  // 创建右子节点,并连接到根节点  root->right = createNode(3);  // 创建左子节点的左子节点,并连接到左子节点  root->left->left = createNode(4);  // 创建左子节点的右子节点,并连接到左子节点  root->left->right = createNode(5);  // 打印先序遍历的提示信息  printf("递归先序遍历结果:");  // 调用先序遍历函数,遍历整棵树  preorderTraversal(root);  // 注意:此代码示例中未包含释放已分配内存的代码,实际使用时应注意内存管理  return 0; // 程序正常结束  
}

C++实现(递归实现)

#include <iostream> // 引入输入输出流库,用于cout和endl  
#include <stack> // 引入栈容器库,用于实现非递归遍历  using namespace std; // 使用标准命名空间,避免每次调用标准库时都要加std::前缀  // 定义二叉树节点结构体  
struct TreeNode {  int val; // 节点的值  TreeNode *left; // 指向左子节点的指针  TreeNode *right; // 指向右子节点的指针  // 构造函数,用于创建新节点并初始化其值和子节点指针  TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
};  // 非递归先序遍历函数  
// 参数:root - 要遍历的二叉树的根节点  
void preorderTraversal(TreeNode* root) {  if (root == nullptr) return; // 如果根节点为空,则直接返回  stack<TreeNode*> s; // 创建一个栈,用于存储待访问的节点指针  s.push(root); // 将根节点指针入栈  // 当栈不为空时,继续循环  while (!s.empty()) {  // 从栈顶获取节点指针,并访问其值(即先序访问)  TreeNode* node = s.top(); // 获取栈顶节点指针  s.pop(); // 将栈顶节点指针出栈  cout << node->val << " "; // 输出节点的值  // 注意:这里先将右子节点入栈,再将左子节点入栈  // 这样做是为了保证在出栈时左子节点先于右子节点被访问  // 因为栈是后进先出(LIFO)的数据结构  if (node->right) s.push(node->right); // 如果右子节点存在,则入栈  if (node->left) s.push(node->left); // 如果左子节点存在,则入栈  }  
}  int main() 
{  // 构建示例二叉树  // 创建根节点并初始化  TreeNode* root = new TreeNode(1);  // 创建左子节点并连接到根节点  root->left = new TreeNode(2);  // 创建右子节点并连接到根节点  root->right = new TreeNode(3);  // 创建左子节点的左子节点并连接到左子节点  root->left->left = new TreeNode(4);  // 创建左子节点的右子节点并连接到左子节点  root->left->right = new TreeNode(5);  // 输出非递归先序遍历的提示信息  cout << "非递归先序遍历结果:";  // 调用非递归先序遍历函数,遍历整棵树  preorderTraversal(root);  // 注意:此代码示例中未包含释放已分配内存的代码,实际使用时应注意内存管理  // 在实际应用中,应在遍历完成后释放所有动态分配的内存,以避免内存泄漏  return 0; // 程序正常结束  
}

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

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

相关文章

OpenCV开发笔记(八十二):两图拼接使用渐进色蒙版场景过渡缝隙

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/143432922 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

Unity程序化生成地形

制作地形&#xff1a; 绘制方块逐个绘制方块并加噪波高度删除Gizmos和逐个绘制 1.draw quad using System.Collections; using System.Collections.Generic; using UnityEngine;[RequireComponent(typeof(MeshFilter))] public class mesh_generator : MonoBehaviour {Mesh m…

基于MoviNet检测视频中危险暴力行为

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【Faster & Mask R-CNN模型实现啤酒瓶瑕疵检测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生…

Java项目实战II基于Java+Spring Boot+MySQL的桂林旅游景点导游平台(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 基于Java、…

每日读则推(十四)——Meta Movie Gen: the most advanced media foundation models to-date

premiere n.首映,首次公演 v.首次公演(戏剧、音乐、电影) a.首要的,最早的 Today we’re premiering Meta Movie Gen: the most advanced media foundation models to-date. 迄今,到现在为止 …

整数越界详解

目录 一、整数类型的范围 二、整数越界的原因 三、整数越界的示例 1.算术运算导致的整数越界 2.位运算导致的整数越界 3.数据类型转换导致的整数越界 四、整数越界的解决方法 在编程中&#xff0c;整数越界是一个需要特别注意的问题。当整数的计算结果超出了其所能表…

深度学习基础知识-编解码结构理论超详细讲解

编解码结构&#xff08;Encoder-Decoder&#xff09;是一种应用广泛且高效的神经网络架构&#xff0c;最早用于序列到序列&#xff08;Seq2Seq&#xff09;任务&#xff0c;如机器翻译、图像生成、文本生成等。随着深度学习的发展&#xff0c;编解码结构不断演变出多种模型变体…

Yolo系列 Yolo v4简介

目录 简介 YOLOv4的特点 1、数据增强&#xff1a;马赛克数据增强&#xff08;Mosaic Data Augmentation&#xff09; 2、 防止过拟合的方法DropBlock 3、标签平滑&#xff08;Label Smoothing&#xff09; 4、损失函数 &#xff1a;GIOU损失、DIOU损失、CIOU损失 &#x…

C语言的数组地址 数组的遍历与练习

1.int main(void) { int a[5] { 10,20,30,40,50 };//数组间的元素地址相连的 int* p; printf("%d\n", &a[0]); printf("%d\n", &a[1]); printf("%d\n", &a[2]); printf("%d\n", &a[3]); …

Python实现SSA智能麻雀搜索算法优化XGBoost-MLP回归模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着大数据技术的迅猛发展&#xff0c;机器学习模型在各行各业的应用越来越广泛。特别是在回归任务…

nginx 设置多个代理服务器(nginx多代理)

修改配置文件 nginx.conf 修改前的内容&#xff0c;如下&#xff1a; worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 80…

如何找到网上爆款内容,快速复制扩大品牌声量

社媒内容爆款复制是现代营销中的一个重要策略&#xff0c;它对于提升品牌声量、曝光度和知名度具有显著效果。 首先什么是爆款&#xff1f; 爆款内容指的是在社交媒体或其他在线平台上迅速获得大量关注、分享和讨论的内容。 准确、及时找到这部分品牌相关的爆款内容&#xf…

2024年10月文章一览

2024年10月编程人总共更新了21篇文章&#xff1a; 1.2024年9月文章一览 2.《Programming from the Ground Up》阅读笔记&#xff1a;p147-p180 3.《Programming from the Ground Up》阅读笔记&#xff1a;p181-p216 4.《Programming from the Ground Up》阅读笔记&#xff…

Git连接码云-保姆级教学(连接Gitee失败的解决)

Git介绍 码云连接 一、Git介绍 二、Git的工作机制 下载链接&#xff1a;Git - 下载软件包 三、使用步骤 创建一个wss的文件夹&#xff0c;作为‘工作空间’ 四、连接码云账号 五、连接Gitee失败的解决方法 一、Git介绍 Git是一个免费的、开源的分布式版本控制…

KINGBASE部署

环境&#xff1a;x86_64 系统&#xff1a;centos7.9 数据库–版本&#xff1a;KingbaseES_V008R006C008B0014_Lin64_install 授权文件–版本&#xff1a;V008R006-license-企业版-90天 一 前置要求 1.1. 硬件环境要求 KingbaseES支持通用X86_64、龙芯、飞腾、鲲鹏等国产C…

Java并发常见面试题总结(下)

Map&#xff08;重要&#xff09; HashMap 和 Hashtable 的区别 线程是否安全&#xff1a; HashMap 是非线程安全的&#xff0c;Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过synchronized 修饰。&#xff08;如果你要保证线程安全的话就使用 ConcurrentHashMa…

Java - 免费图文识别_Java_免费_图片转文字_文字识别_spring ai_spring ai alibaba

本文主要是介绍借助阿里云免费的大模型额度来做高质量的图转文识别&#xff0c;图片转文字&#xff0c;或者文字识别都可以使用&#xff0c;比传统的OCR模式要直接和高效很多 。 本文使用的技术是spring ai qwen vl 。 Qwen vl有 100万Token 免费额度&#xff0c;可以用来免费…

基于边缘计算的智能门禁系统架构设计分析

案例 阅读以下关于 Web 系统架构设计的叙述&#xff0c;回答问题1至问题3。 【说明】 某公司拟开发一套基于边缘计算的智能门禁系统&#xff0c;用于如园区、新零售、工业现场等存在来访被访业务的场景。来访者在来访前&#xff0c;可以通过线上提前预约的方式将自己的个人信息…

基于SpringBoot+Vue的购物商城系统【前后端分离】

基于SpringBootVue的购物商城系统设计与实现 摘要 随着互联网技术的不断发展&#xff0c;线上购物已经成为人们日常生活中不可或缺的一部分。本博客将详细介绍一个基于Spring Boot和Vue的购物商城系统的设计与实现。该系统包含了商品展示、购物车管理、订单处理、用户管理等模块…