树的4种遍历

目录

树的四种遍历方式的总结

1. 前序遍历(Pre-order Traversal)

2. 中序遍历(In-order Traversal)

3. 后序遍历(Post-order Traversal)

4. 层序遍历(Level-order Traversal 或 广度优先遍历,Breadth-First Traversal)

以下是这四种遍历方式的C语言实现示例:

1. 定义二叉树节点

2. 前序遍历(根-左-右)

3. 中序遍历(左-根-右)

4. 后序遍历(左-右-根)

5. 层序遍历(广度优先遍历)


树的四种遍历方式的总结

树的四种遍历方式(前序遍历、中序遍历、后序遍历和层序遍历)是理解和操作二叉树的基础。以下是这四种遍历方式的总结:

1. 前序遍历(Pre-order Traversal)

访问顺序:根节点 -> 左子树 -> 右子树
递归实现简单直观,先访问根节点,然后递归遍历左子树,最后递归遍历右子树。
非递归实现通常使用栈来辅助遍历,先将根节点压栈,然后在循环中出栈并访问当前节点,接着将右子节点和左子节点依次压栈(注意顺序)。


2. 中序遍历(In-order Traversal)

访问顺序:左子树 -> 根节点 -> 右子树
在二叉搜索树中,中序遍历的结果是一个有序序列。
递归实现时,先递归遍历左子树,然后访问根节点,最后递归遍历右子树。
非递归实现同样使用栈,但需要标记节点来源(是否来自左子树)来确保先遍历左子树。


3. 后序遍历(Post-order Traversal)

访问顺序:左子树 -> 右子树 -> 根节点
递归实现简单,但非递归实现相对复杂。
非递归实现通常使用两个栈或结合栈和指针来追踪节点和它们的子节点,确保在访问根节点之前已经遍历了左右子树。


4. 层序遍历(Level-order Traversal 或 广度优先遍历,Breadth-First Traversal)

访问顺序:从上到下,从左到右(即按层次顺序)
使用队列来辅助实现,先将根节点入队,然后在循环中每次出队一个节点并访问,接着将其非空子节点依次入队(通常先左后右)。
层序遍历在二叉树的层次结构分析、图的广度优先搜索等场景中非常有用。
注意事项
递归实现简洁明了,但可能导致栈溢出,特别是在处理深度很大的树时。
非递归实现通常使用栈或队列等数据结构来辅助遍历,需要注意数据结构的正确操作和管理。
在遍历过程中,要时刻注意空指针的情况,避免访问空指针导致的程序崩溃。
根据不同的应用场景选择合适的遍历方式,例如在二叉搜索树中,中序遍历的结果是有序的,而在分析树的层次结构时,层序遍历更为直观。

以下是这四种遍历方式的C语言实现示例:

1. 定义二叉树节点


#include <stdio.h>
#include <stdlib.h>typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;
} TreeNode;

2. 前序遍历(根-左-右)

void preOrderTraversal(TreeNode* root) {if (root == NULL) return;printf("%d ", root->val);preOrderTraversal(root->left);preOrderTraversal(root->right);
}

3. 中序遍历(左-根-右)
 

void inOrderTraversal(TreeNode* root) {if (root == NULL) return;inOrderTraversal(root->left);printf("%d ", root->val);inOrderTraversal(root->right);
}

4. 后序遍历(左-右-根)
 

void postOrderTraversal(TreeNode* root) {if (root == NULL) return;postOrderTraversal(root->left);postOrderTraversal(root->right);printf("%d ", root->val);
}

5. 层序遍历(广度优先遍历)

在C语言中实现二叉树的层序遍历(广度优先遍历)需要借助队列数据结构。由于C标准库没有直接提供队列,我们可以使用数组或链表配合指针来模拟队列的行为。以下是一个使用数组模拟队列实现层序遍历的示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// 定义二叉树节点

typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;
} TreeNode;

// 创建一个新节点

TreeNode* createNode(int val) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));if (!newNode) {exit(EXIT_FAILURE);}newNode->val = val;newNode->left = NULL;newNode->right = NULL;return newNode;
}

// 层序遍历(广度优先遍历)
 

void levelOrderTraversal(TreeNode* root) {if (root == NULL) return;// 创建一个队列TreeNode* queue[1000]; // 假设队列最大长度为1000int front = 0, rear = 0;// 将根节点入队queue[rear++] = root;while (front < rear) {// 出队一个节点TreeNode* node = queue[front++];printf("%d ", node->val);// 将左孩子和右孩子入队if (node->left) {queue[rear++] = node->left;}if (node->right) {queue[rear++] = node->right;}}
}int main() {// 创建一个简单的二叉树进行测试TreeNode* root = createNode(1);root->left = createNode(2);root->right = createNode(3);root->left->left = createNode(4);root->left->right = createNode(5);// 层序遍历二叉树levelOrderTraversal(root);// 清理内存(这里省略了详细的内存清理代码)return 0;
}


在上面的代码中,我们定义了一个固定大小的队列数组queue,以及两个指针front和rear来模拟队列的头部和尾部。需要注意的是,这里假设了队列的最大长度为1000,但在实际应用中,我们可能需要动态分配内存或使用链表来实现一个更灵活的队列。

在levelOrderTraversal函数中,我们首先将根节点入队,然后进入一个循环,直到队列为空。在每次循环中,我们出队一个节点并打印其值,然后将该节点的左孩子和右孩子(如果存在)入队。这样,我们就能按照层次顺序遍历整个二叉树。


注意:上面的层序遍历示例使用了C++的std::queue,因为C标准库并没有直接提供队列的数据结构。在纯C中,你需要自己实现一个队列或者使用数组来模拟队列。

在实际使用时,你可以根据需要选择适合的遍历方式。

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

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

相关文章

引入别人的安卓项目报错

buildscript { repositories { google() jcenter() } dependencies { classpath com.android.tools.build:gradle:4.1.0 // 使用最新版本的插件 } } allprojects { repositories { google() jcenter() } } 在…

Feign是如何发送http请求的底层源码

Feign 的底层源码涉及多个组件和库来实际发送 HTTP 请求。Feign 的主要目标是提供一个声明式的 Web Service 客户端接口&#xff0c;而底层实现则依赖于其他库&#xff08;如 OkHttp、Apache HttpClient 等&#xff09;来发送实际的 HTTP 请求。 1、接口代理 当你通过 Feign …

Keil软件仿真的使用

一、软件的初始化设置 初始设置可以按照下图&#xff0c;这里我使用的是STM32F103C8T6&#xff0c;所以单片机型号为STM32F103C8&#xff0c;这个设置在Debug目录下。然后进行时钟的设置&#xff0c;我们板上晶振为8M&#xff0c;这里将时钟改为8. 或许有人想问如果是别的型号单…

Effective Java 1 用静态工厂方法代替构造器

知识点上本书需要会Java语法和lang、util、io库&#xff0c;涉及concurrent和function包。 内容上主要和设计模式相关&#xff0c;代码风格力求清晰简洁&#xff0c;代码尽量复用&#xff0c;组件尽量少依赖&#xff0c;错误尽早发现。 第1个经验法则&#xff1a;用静态工厂方…

Chroium 源码目录结构分析(1):源码目录体积一栏

获取源码 首先&#xff0c;我们拉一份最新的源代码&#xff08;笔者是2024.6.6日拉取的&#xff09;&#xff1a; fetch --nohistory chromium 源码预处理 如果运行build&#xff0c;会生成许多生成的代码&#xff0c;因此我们不运行build。 然后&#xff0c;把干扰后续分析…

sqlilabs靶场安装

05-sqllabs靶场安装 1 安装 1 把靶场sqli-labs-master.zip上传到 /opt/lampp/htdocs 目录下 2 解压缩 unzip sqli-labs-master.zip3 数据库配置 找到配置文件,修改数据库配置信息 用户名密码&#xff0c;修改为你lampp下mysql的用户名密码&#xff0c;root/123456host:la…

语法的时态1——一般现在时(1)

定义&#xff1a;一般现在时用来表示经常发生的动作&#xff0c;以及客观事实。 一般现在时的构成以及标志词 1.一般现在时的结构 &#xff08;1&#xff09;主系表结构 构成&#xff1a;主语be(am,is,ear)其他。属于状态句。 I…

贪吃蛇双人模式设计(2)

敲上瘾-CSDN博客控制台程序设置_c语言控制程序窗口大小-CSDN博客贪吃蛇小游戏_贪吃蛇小游戏csdn-CSDN博客​​​​​​​ 一、功能实现&#xff1a; 玩家1使用↓ → ← ↑按键来操作蛇的方向&#xff0c;使用右Shift键加速&#xff0c;右Ctrl键减速玩家2使用W A S D按键来操…

matlab演示地月碰撞

代码 function EarthMoonCollisionSimulation()% 初始化参数earth_radius 6371; % 地球半径&#xff0c;单位&#xff1a;公里moon_radius 1737; % 月球半径&#xff0c;单位&#xff1a;公里distance 384400; % 地月距离&#xff0c;单位&#xff1a;公里collision_tim…

Astar路径规划算法复现-python实现

# -*- coding: utf-8 -*- """ Created on Fri May 24 09:04:23 2024"""import os import sys import math import heapq import matplotlib.pyplot as plt import time 传统A*算法 class Astar:AStar set the cost heuristics as the priorityA…

Kafka集成flume

1.flume作为生产者集成Kafka kafka作为flume的sink&#xff0c;扮演消费者角色 1.1 flume配置文件 vim $kafka/jobs/flume-kafka.conf # agent a1.sources r1 a1.sinks k1 a1.channels c1 c2# Describe/configure the source a1.sources.r1.type TAILDIR #记录最后监控文件…

基于python-CNN深度学习的水瓶是否装满水识别-含数据集+pyqt界面

代码下载地址&#xff1a; https://download.csdn.net/download/qq_34904125/89374853 本代码是基于python pytorch环境安装的。 下载本代码后&#xff0c;有个requirement.txt文本&#xff0c;里面介绍了如何安装环境&#xff0c;环境需要自行配置。 或可直接参考下面博文…

绘唐2.5一键追爆款2.5免费版

免费分享给您 小说推文工具是一种用于在社交媒体上宣传和推广小说的工具。它可以帮助作者将小说的内容和相关信息以推文的形式快速发布在各种社交媒体平台上&#xff0c;吸引读者的注意力并增加小说的曝光度。 以下是一些小说推文工具可能具备的功能&#xff1a; 1. 编辑和排…

【linux】进程控制——进程创建,进程退出,进程等待

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 相关文章 【Linux】进程地址空间-CSDN博客 【linux】详解linux基本指令-CSDN博客 目录 进程控制概述 创建子进程 fork函数 父子进程执行流 原理刨析 常见用法 出错原因 进程退出 概…

MyBatis-Plus学习总结

一.快速入门 (一)简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window) 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 (二)快速入门 1.准备数据库脚本 2.准备bo…

六、Docker Swarm、Docker Stack和Portainer的使用

六、Docker swarm和Docker stack的使用 系列文章目录1.Docker swarm1.简介2.docker swarm常用命令3.docker node常用命令4.docker service常用命令5.实战案例6.参考文章 2.Docker stack1.简介3.Docker stack常用命令4.实战案例5.常见问题及调错方式1.查看报错信息并尝试解决&am…

【数学】浙江省中考数学典型若:n^n=2^(2048)求√n

浙江省中考数学典型 若&#xff1a; n n 2 2048 n^n2^{2048} nn22048求 n \sqrt{n} n ​ 解 幂运算公式1 a n a t 1 t n a^na^{t \times \frac{1}{t}\times n} anatt1​n n n 2 2048 2 t 1 t 2048 ( 2 t ) 2048 t n^n2^{2048}2^{t\times\frac{1}{t}\times 2048}(2^t…

SpringBootWeb 篇-深入了解 Redis 五种类型命令与如何在 Java 中操作 Redis

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Redis 概述 1.1 Redis 下载与安装 2.0 Redis 数据类型 3.0 Redis 常见五种类型的命令 3.1 字符串操作命令 3.2 哈希操作命令 3.3 列表操作命令 3.4 集合操作命令 …

前端学习笔记(一)

前端学习笔记(一) 网页基本框架 标签:写在html的代码单标签:一般是功能标签 有特别的功能双标签:一般包裹内容 显示东西 双标签一般闭合而且后面的标签的<>里的第一个字符必须使用/,例如,<html></html>基本框架 <html></html> 网页的核心…

7-43 排列问题

排列问题 分数 10 全屏浏览 切换布局 作者 雷丽兰 单位 宜春学院 全排列问题 输出自然数1至n中n个数字的全排列&#xff08;1≤n≤9&#xff09;&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式: 一个自然数 输出格式: 由1到n中n个数字组成的…