当前位置: 首页 > news >正文

【数据结构】2——二叉树遍历

数据结构2——二叉树遍历

单纯记录


文章目录

  • 数据结构2——二叉树遍历
  • 一、二叉树遍历
    • 1,先序遍历:根左右
      • 递归实现
      • 非递归实现(栈)
    • 2.中序遍历:左根右
      • 递归
      • 非递归
    • 3 .后序遍历:左右根
      • 递归
      • 非递归(两个栈)
  • 二、层次遍历(广度优先遍历)
    • 队列实现


一、二叉树遍历

1,先序遍历:根左右

     1/   \2     3/ \   / \
4   5 6   7首先访问根节点 1。
然后遍历左子树:
访问根节点 2。
遍历左子树:访问节点 4。
遍历右子树:访问节点 5。
最后遍历右子树:
访问根节点 3。
遍历左子树:访问节点 6。
遍历右子树:访问节点 7。
所以,该二叉树的先序遍历结果为:1 2 4 5 3 6 7

递归实现

class TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef preorderTraversal(root):if root is not None:print(root.value, end=" ")  # 访问根节点preorderTraversal(root.left)  # 递归访问左子树preorderTraversal(root.right)  # 递归访问右子树# 创建节点
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)# 执行先序遍历
preorderTraversal(root)

非递归实现(栈)

def preorderTraversalIterative(root):# 检查根节点是否为空,若为空则直接返回if root is None:return# 初始化栈并将根节点推入栈中stack = [root]# 当栈不为空时循环执行while stack:# 弹出栈顶节点并输出其值node = stack.pop()print(node.value, end=" ")# 先将右子节点推入栈(因为先序遍历是先访问左子节点)if node.right:stack.append(node.right)# 再将左子节点推入栈if node.left:stack.append(node.left)# 使用迭代方法执行先序遍历
preorderTraversalIterative(root)

2.中序遍历:左根右

        1/ \2   3/ \   \4   5   6

递归

class TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef inorderTraversal(root):if root is not None:inorderTraversal(root.left)  # 递归访问左子树print(root.value, end=" ")  # 访问根节点inorderTraversal(root.right)  # 递归访问右子树# 创建节点
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)# 执行中序遍历
inorderTraversal(root)

非递归

过程:

  • 根节点1入栈,移动到左子节点2。
  • 节点2入栈,移动到左子节点4。
  • 节点4入栈,由于4没有左子节点,从栈中弹出节点4,访问(打印)节点4。
  • 移动到节点4的右子节点5,节点5入栈,由于5没有左子节点,从栈中弹出节点5,访问(打印)节点5。
  • 回到节点2,移动到节点2的右子节点5,节点5已经访问过,移动到节点2的右子节点3。
  • 节点3入栈,移动到左子节点6。
  • 节点6入栈,由于6没有左子节点,从栈中弹出节点6,访问(打印)节点6。
  • 回到节点3,由于3没有右子节点,从栈中弹出节点3,访问(打印)节点3。
  • 回到节点1,由于1没有右子节点,从栈中弹出节点1,访问(打印)节点1。
  • 遍历结束。
  • 非递归中序遍历的输出结果为:4, 5, 2, 6, 3, 1

def inorderTraversalIterative(root):stack = []  # 创建一个空栈current = root  # 初始化当前节点为根节点while stack or current:  # 当栈不为空或者当前节点不为空时循环while current:  # 当前节点不为空时,一直向左遍历stack.append(current)  # 将当前节点压入栈中current = current.left  # 移动到左子节点current = stack.pop()  # 弹出栈顶元素作为当前节点print(current.value, end=" ")  # 访问当前节点current = current.right  # 移动到右子节点# 使用迭代方法执行中序遍历
inorderTraversalIterative(root)

3 .后序遍历:左右根

        1/ \2   3/ \   \4   5   6

递归

class TreeNode:def __init__(self, value):self.value = value  # 节点存储的值self.left = None    # 左子节点初始为空self.right = None   # 右子节点初始为空def postorderTraversal(root):# 检查当前节点是否为空if root is not None:# 递归遍历左子树postorderTraversal(root.left)# 递归遍历右子树postorderTraversal(root.right)# 访问根节点print(root.value, end=" ")# 创建具体的二叉树节点
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)# 执行后序遍历
postorderTraversal(root)

非递归(两个栈)

def postorderTraversalIterative(root):if not root:return# stack1 用于存储节点,stack2 用于逆序输出stack1, stack2 = [root], []while stack1:node = stack1.pop()if node:stack2.append(node)# 先压入左子节点,再压入右子节点,保证左子节点在栈内先弹出if node.left:stack1.append(node.left)if node.right:stack1.append(node.right)# 从栈中弹出节点并访问,由于是逆序访问,所以输出顺序是正确的while stack2:node = stack2.pop()print(node.value, end=" ")# 使用迭代方法执行后序遍历
postorderTraversalIterative(root)

二、层次遍历(广度优先遍历)

首先访问根节点,然后是所有子节点,接着是子节点的子节点,以此类推。这种遍历方式通常用于查找最短路径或最小深度。

        1/ \2   3/ \   \4   5   6

按照层次遍历的具体步骤:
创建一个空队列。

  • 将根节点1入队。
  • 循环开始:
    a. 出队节点1,访问它(打印1)。
    b. 将节点1的左子节点2和右子节点3入队。
  • 下一次循环:
    a. 出队节点2,访问它(打印2)。
    b. 将节点2的左子节点4和右子节点5入队。
    c. 出队节点3,访问它(打印3)。
    d. 将节点3的右子节点6入队。
  • 继续循环:
    a. 出队节点4,访问它(打印4)。
    b. 出队节点5,访问它(打印5)。
    c. 出队节点6,访问它(打印6)。
  • 队列为空,遍历结束。

队列实现

from collections import dequeclass TreeNode:def __init__(self, value):self.value = value  # 节点存储的值self.left = None    # 左子节点初始为空self.right = None   # 右子节点初始为空def levelOrderTraversal(root):if not root:return []result = []  # 存储遍历的结果queue = deque([root])  # 使用deque(双端队列)作为队列while queue:node = queue.popleft()  # 从队列中取出一个节点result.append(node.value)  # 将节点值添加到结果列表中if node.left:queue.append(node.left)  # 将左子节点添加到队列if node.right:queue.append(node.right)  # 将右子节点添加到队列return result# 创建具体的二叉树节点
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)# 执行层次遍历
print(levelOrderTraversal(root))

相关文章:

【数据结构】2——二叉树遍历

数据结构2——二叉树遍历 单纯记录 文章目录 数据结构2——二叉树遍历一、二叉树遍历1,先序遍历:根左右递归实现非递归实现(栈) 2.中序遍历:左根右递归非递归 3 .后序遍历:左右根递归非递归(两…...

数据结构应用实例(五)——关键路径

Content: 一、问题描述二、算法思想三、代码实现四、小结 一、问题描述 设计实现 AOE 网的关键活动与关键路径问题; 二、算法思想 获取拓扑序列;计算节点的最早开始时间 v e [ i ] ve[i] ve[i];计算节点的最晚开始时间 v l [ j ] vl[j] v…...

组播 2024 9 11

PIM(Protocol Independent Multicast)是一种常用的组播路由协议,其独立于底层的单播路由协议,能够在多种网络环境中有效地实现多播路由功能。PIM主要有两种模式:PIM Sparse Mode (PIM-SM) 和 PIM Dense Mode (PIM-DM)&…...

揭秘开发者的效率倍增器:编程工具的选择与应用

文章目录 每日一句正能量前言工具介绍功能特点:使用场景:提高工作效率的方式: 效率对比未来趋势后记 每日一句正能量 这推开心窗之人,可以是亲朋好友,也可以是陌客路人,可以是德高望重的哲人名流&#xff0…...

在AI的时代,程序员如何才不被淘汰

随着人工智能技术的迅猛发展,大模型(Large Language Models, LLMs)正逐渐成为IT行业的热点。对于程序员来说,转行大模型领域不仅意味着新的机遇,也面临着诸多挑战。本文将探讨程序员转行大模型的机遇与挑战&#xff0c…...

tabBar设置底部菜单选项以及iconfont图标,setTabBar设置TabBar和下拉刷新API

tabBartabBar属性:设置底部 tab 的表现 ​ ​ ​ ​ 首先在pages.json页面写一个tabBar对象,里面放入list对象数组,里面至少要有2个、最多5个 tab, 如果只有一个tab的话,H5(浏览器)依然可以显示底部有一个导航栏,如果没有,需要重启后才有,小程序则报错,只有2个以上才可以…...

2024C题prompt

题目 我正在进行数学建模,需要你为我提供帮助。下面我会将赛题背景和问题发送给你,请你为我提供比赛思路和指导。 以下是赛题背景和赛题说明,不是问题: 农作物的种植策略 根据乡村的实际情况,充分利用有限的耕地资源&#xff0c…...

Numpy中数组的形状处理

目录 将多维数组降为一维数组竖直方向或水平方向数组的堆叠 数组形状处理的手段主要有reshape,resize,ravel,flatten,vstack,hstack,row_stack,column_stack,下面通过简单 的案例来解释这些方法…...

【动态规划】子序列问题二(数组中不连续的一段)

子序列问题二 1.最长定差子序列2.最长的斐波那契子序列的长度3.最长等差数列4.等差数列划分 II - 子序列 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&am…...

可视耳勺方便吗?可视耳勺热销第一名品牌!

在生活中,耳部清洁是我们常常会关注却又容易忽视细节的一项日常护理。传统挖耳勺有着不可视的局限性,只能凭感觉和经验反复刮蹭耳朵,很容易将耳垢越捅越深,而且还会刮伤耳道。因此,可视耳勺应运而生,它通过…...

micropython 3-wire spi 9bit 写入的问题

网上猛找把,没有,找不到,mpy不愧是没朋友的缩写,没有咋办,自己造! 此库特别适用那些rgb屏的初始化,大多用3线spi,好家伙rgb用了十多个引脚现在想起来省引脚了是吧,就差这…...

导致JVM内存泄露的ThreadLocal详解

1. ThreadLocal介绍 1.1 什么是ThreadLocal Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来…...

windows下关闭解除占用端口的进程

环境:windows 10 场景:启动某一应用程序时,提示其他应用已占用此端口,比如端口2425。 解决步骤: 1/3、打开windows的命令提示符,输入以下命令,查找占用此端口2425的PID号: # win…...

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前数据吞吐量(Python)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK里函数来获取相机当前数据吞吐量(Python) Baumer工业相机Baumer工业相机的数据吞吐量的技术背景CameraExplorer如何查看相机吞吐量信息在NEOAPI SDK里通过函数获取相机接口吞吐量 Baumer工业相机通过NEOAPI…...

版权与开源协议:一场创新与自由的边界之争

在数字时代的浪潮中,版权与开源协议作为知识产权领域的两大支柱,既相互依存又暗自较劲,共同绘制着科技创新的宏伟蓝图。本文将带您深入这场创新与自由的边界之争,探讨版权与开源协议之间的微妙关系,以及它们如何共同推…...

学生用的蓝牙耳机推荐有哪些?实测四款实力出众机型!

在当今数字化学习环境中,学生对蓝牙耳机的需求日益增长,无论是在线课程的学习、图书馆的集中阅读还是日常通勤中的音频资料复习,一款性能优异、舒适度高且价格合理的蓝牙耳机对学生来说至关重要,面对市场上琳琅满目的产品选择&…...

MIT6.824 课程-GFS

GFS 原文:https://zhuanlan.zhihu.com/p/113161014 搬运用于参考学习 概述 存储(Storage)是一个非常关键的抽象,用途广泛。 GFS 论文还提到了很多关于容错、备份和一致性的问题。 GFS 本身是 Google 内部一个很成功的实用系统&…...

力扣第200题 岛屿数量

前言 记录一下刷题历程 力扣第200题 岛屿数量 岛屿数量 原题目: 给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平…...

协议头,wireshark,http

目录 协议头 ip头 udp头 mac层 网络工具 telnet wireshark Http 一、HTTP 协议介绍 二、HTTP 协议的工作过程 三、使用抓包工具抓取报文 四、获取到http请求报文: 五、http请求(request) (一)、认识URL 项…...

vscode ssh离线远程连接ubuntu调试

遇见问题: 1 ssh连接上无法启动服务器的虚拟环境; 2 ssh连接上启动服务器的虚拟环境后无法打断点; 对于问题需要参考下面连接安装python和debugy的插件拓展,并且配置json文件link。VSCode - 离线安装扩展python插件教程_vscode…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...