当前位置: 首页 > 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))

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ThinkCMF框架任意内容包含漏洞的讲解
  • ⭐Unity 安卓环境中正确地读取和处理 XML 文件
  • OpengGL教程(三)---使用VAO和VBO方式绘制三角形
  • python学习第九节:爬虫实战-抓取地址库
  • BMC+ssh和共享平台的Ironic服务,实现裸金属服务器的远程管理与调用
  • Java8 流的简单介绍
  • 如何防止ZIP压缩文件被随意打开?
  • 洞悉地下寒潮,守护温暖家园:智能CG-68冻土传感器监测系统
  • Windows 环境下 vscode 配置 C/C++ 环境
  • Vue3+setup实现父子组件单表增删改查写法模板
  • 掌握MATLAB中的数据类型转换技巧
  • java之认识异常
  • matlab绘制不同区域不同色彩的图,并显示数据(代码)
  • 【C++ 高频面试题】new、delete 与 malloc、free的区别
  • 64位系统中不支持In.vi与Out.vi的原因
  • 网络传输文件的问题
  • 分享的文章《人生如棋》
  • 【node学习】协程
  • 【面试系列】之二:关于js原型
  • dva中组件的懒加载
  • Java多态
  • JS学习笔记——闭包
  • Shadow DOM 内部构造及如何构建独立组件
  • Vue 动态创建 component
  • 官方解决所有 npm 全局安装权限问题
  • 全栈开发——Linux
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 新书推荐|Windows黑客编程技术详解
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 正则学习笔记
  • 【云吞铺子】性能抖动剖析(二)
  • 湖北分布式智能数据采集方法有哪些?
  • ​数据结构之初始二叉树(3)
  • ​一些不规范的GTID使用场景
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (7)摄像机和云台
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (PySpark)RDD实验实战——求商品销量排行
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (苍穹外卖)day03菜品管理
  • (待修改)PyG安装步骤
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (翻译)terry crowley: 写给程序员
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转载)(官方)UE4--图像编程----着色器开发
  • .htaccess配置重写url引擎
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .Net 6.0--通用帮助类--FileHelper
  • .NET Core中的去虚
  • .net mvc actionresult 返回字符串_.NET架构师知识普及