【数据结构4】树的实例-模拟文件系统、二叉树的遍历(先序遍历、中序遍历、后序遍历、层次遍历)

1 树和二叉树
2 树的实例-模拟文件系统
3 二叉树
3.1 二叉树的遍历
二叉树的先序遍历
二叉树的中序遍历
二叉树的后序遍历
二叉树的层次遍历

1 树

树是一种数据结构
比如:目录结构
树是一种可以递归定义的数据结构树是由n个节点组成的集合:如果n=0,那这是一棵空树;如果n>0,那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树

在这里插入图片描述

2 树的实例-模拟文件系统

class Node:"""表示文件系统树中的一个节点。属性:name (str): 节点的名称。对于目录,它以 '/' 结尾,对于文件,不以 '/' 结尾。type (str): 节点的类型,'dir' 代表目录,'file' 代表文件。children (list): 该节点的子节点列表。仅对目录节点有效。parent (Node): 该节点的父节点。如果是根节点,则为 None。"""def __init__(self, name, type='dir'):"""初始化一个新的节点。:param name: 节点的名称。目录名称通常以 '/' 结尾,文件名称不以 '/' 结尾。:param type: 节点的类型。默认为 'dir'(目录),可以设置为 'file'(文件)以表示文件节点。"""self.name = nameself.type = typeself.children = []  # 初始化为空列表,目录节点可以包含子节点self.parent = None  # 父节点初始化为 Nonedef __repr__(self):return self.nameclass FileSystemTree:"""表示一个文件系统树,支持创建目录、列出目录内容以及切换目录等操作。属性:root (Node): 文件系统树的根节点,初始化时创建。now (Node): 当前工作目录。操作会影响该目录。"""def __init__(self):"""初始化文件系统树,创建根目录,并将当前工作目录设置为根目录。"""self.root = Node("/")  # 创建根目录,名称为 "/"self.now = self.root  # 将当前工作目录设置为根目录def mkdir(self, name):"""在当前工作目录下创建一个新的目录。:param name: 新目录的名称。必须以 '/' 结尾。如果没有结尾的 '/', 会自动添加。"""if name[-1] != "/":  # 检查目录名称是否以 '/' 结尾name += '/'  # 添加 '/' 以确保目录名称正确node = Node(name)  # 创建新的目录节点self.now.children.append(node)  # 将新目录添加到当前工作目录的子节点列表中node.parent = self.now  # 设置新目录的父节点为当前工作目录def ls(self):"""展示当前工作目录下的所有子节点。:return: 当前目录下的子节点列表(包括目录和文件)。"""return self.now.children  # 返回当前目录的子节点列表def cd(self, name):"""切换到指定的目录。支持绝对路径和相对路径。:param name: 目标目录的路径。可以是绝对路径(以 '/' 开头)或相对路径(不以 '/' 开头)。:return: 无返回值。成功切换目录时,更新当前工作目录。:raises ValueError: 如果指定的路径无效或目录不存在,抛出异常。"""if name[-1] != "/":  # 确保目录名称以 '/' 结尾name += '/'# 处理路径components = name.split('/')  # 将路径分解为各个部分node = self.now  # 从当前工作目录开始遍历for component in components:if component == '..':# 如果路径部分是 '..',则返回到上一级目录if node.parent is not None:node = node.parentelif component and component != '/':# 如果路径部分是有效的目录名,则查找该目录found = Falsefor child in node.children:if child.name == component + '/':node = child  # 找到目标目录,更新当前节点found = Truebreakif not found:# 如果没有找到目标目录,则抛出异常raise ValueError('无效的目录')self.now = node  # 更新当前工作目录为目标目录tree = FileSystemTree()
tree.mkdir('var/')
tree.mkdir('bin/')
tree.mkdir('bin/python')
tree.mkdir('usr/')print(tree.root.children)
print(tree.ls())
print(tree.cd('bin/'))
tree.cd("../")
print(tree.ls())

3 二叉树

二叉树的链式存储:将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接。节点定义:
class BiTreeNode:def __init__(self, data):self.data = dataself.lchild = Noneself.rchild = None

**实现这棵二叉树**
在这里插入图片描述

class BiTreeNode:def __init__(self, data):self.data = dataself.lchild = None  # 左孩子self.rchild = None  # 右孩子a = BiTreeNode('A')
b = BiTreeNode('B')
c = BiTreeNode('C')
d = BiTreeNode('D')
e = BiTreeNode('E')
f = BiTreeNode('F')
g = BiTreeNode('G')e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = froot = e
print(root.lchild.rchild.data)

3.1 二叉树的遍历

二叉树的前序遍历是一种深度优先遍历方式。
遍历顺序为:访问根节点前序遍历左子树前序遍历右子树二叉树的中序遍历也是一种深度优先遍历方式。
遍历顺序为:中序遍历左子树访问根节点中序遍历右子树二叉树的后序遍历也是一种深度优先遍历方式。
遍历顺序为:后序遍历左子树后序遍历右子树访问根节点二叉树的层次遍历(也称为广度优先遍历)是一种按层从上到下、从左到右访问节点的遍历方式。
常用的实现方法是利用队列(Queue)。

在这里插入图片描述

二叉树的前序遍历

def pre_order(root):"""二叉树的前序遍历:param root::return:"""if root:print(root.data, end=',')pre_order(root.lchild)pre_order(root.rchild)pre_order(root)  # E,A,C,B,D,G,F,
class TreeNode:def __init__(self, value=0, left=None, right=None):"""初始化一个二叉树节点。:param value: 节点的值:param left: 左子节点,默认为 None:param right: 右子节点,默认为 None"""self.value = valueself.left = left  # 左子节点self.right = right  # 右子节点def preorder_traversal(root):"""前序遍历二叉树。前序遍历的顺序为:根节点 -> 左子树 -> 右子树。:param root: 二叉树的根节点:return: 节点值的列表,按照前序遍历的顺序"""if root is None:return []  # 如果当前节点为空,则返回空列表# 访问根节点,将其值加入结果列表result = [root.value]# 前序遍历左子树,并将结果拼接到结果列表中result += preorder_traversal(root.left)# 前序遍历右子树,并将结果拼接到结果列表中result += preorder_traversal(root.right)return result# 示例用法
# 构建一个二叉树
#     1
#    / \
#   2   3
#  / \
# 4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 前序遍历
print(preorder_traversal(root))  # 输出 [1, 2, 4, 5, 3]

二叉树的中序遍历

def mid_order(root):"""二叉树的中序遍历:param root::return:"""if root:mid_order(root.lchild)print(root.data, end=',')mid_order(root.rchild)mid_order(root)  # A,B,C,D,E,G,F,
class TreeNode:def __init__(self, value=0, left=None, right=None):"""初始化一个二叉树节点。:param value: 节点的值:param left: 左子节点,默认为 None:param right: 右子节点,默认为 None"""self.value = valueself.left = left  # 左子节点self.right = right  # 右子节点def inorder_traversal(root):"""中序遍历二叉树。中序遍历的顺序为:左子树 -> 根节点 -> 右子树。:param root: 二叉树的根节点:return: 节点值的列表,按照中序遍历的顺序"""if root is None:return []  # 如果当前节点为空,则返回空列表result = []# 先中序遍历左子树,并将结果拼接到结果列表中result += inorder_traversal(root.left)# 然后访问根节点,将其值加入结果列表result.append(root.value)# 最后中序遍历右子树,并将结果拼接到结果列表中result += inorder_traversal(root.right)return result# 示例用法
# 构建一个二叉树
#     1
#    / \
#   2   3
#  / \
# 4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 中序遍历
print(inorder_traversal(root))  # 输出 [4, 2, 5, 1, 3]

二叉树的后序遍历

def post_order(root):"""二叉树的后序遍历:param root::return:"""if root:post_order(root.lchild)post_order(root.rchild)print(root.data, end=',')post_order(root)  # A,C,B,D,G,F,E
class TreeNode:def __init__(self, value=0, left=None, right=None):"""初始化一个二叉树节点。:param value: 节点的值:param left: 左子节点,默认为 None:param right: 右子节点,默认为 None"""self.value = valueself.left = left  # 左子节点self.right = right  # 右子节点def postorder_traversal(root):"""后序遍历二叉树。后序遍历的顺序为:左子树 -> 右子树 -> 根节点。:param root: 二叉树的根节点:return: 节点值的列表,按照后序遍历的顺序"""if root is None:return []  # 如果当前节点为空,则返回空列表result = []# 先后序遍历左子树,并将结果拼接到结果列表中result += postorder_traversal(root.left)# 然后后序遍历右子树,并将结果拼接到结果列表中result += postorder_traversal(root.right)# 最后访问根节点,将其值加入结果列表result.append(root.value)return result# 示例用法
# 构建一个二叉树
#     1
#    / \
#   2   3
#  / \
# 4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 后序遍历
print(postorder_traversal(root))  # 输出 [4, 5, 2, 3, 1]

二叉树的层次遍历

from collections import dequedef level_order(root):"""层次遍历二叉树的函数:param root: 二叉树的根节点:return: None"""# 初始化一个队列,用于层次遍历queue = deque()# 将根节点入队queue.append(root)# 当队列不为空时,继续遍历while len(queue) > 0:# 从队列中取出一个节点node = queue.popleft()# 打印当前节点的数据print(node.data, end=',')# 如果当前节点有左子节点,将左子节点入队if node.lchild:queue.append(node.lchild)# 如果当前节点有右子节点,将右子节点入队if node.rchild:queue.append(node.rchild)level_order(root)  # E,A,G,C,F,B,D,
from collections import dequeclass TreeNode:def __init__(self, value=0, left=None, right=None):"""初始化一个二叉树节点。:param value: 节点的值:param left: 左子节点,默认为 None:param right: 右子节点,默认为 None"""self.value = valueself.left = left  # 左子节点self.right = right  # 右子节点def level_order_traversal(root):"""层次遍历二叉树(广度优先遍历)。层次遍历的顺序为:按层从上到下,从左到右依次访问每个节点。:param root: 二叉树的根节点:return: 节点值的列表,按照层次遍历的顺序"""if root is None:return []  # 如果根节点为空,则返回空列表result = []  # 用于存储遍历结果的列表queue = deque([root])  # 初始化队列,并将根节点加入队列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# 示例用法
# 构建一个二叉树
#     1
#    / \
#   2   3
#  / \
# 4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 层次遍历
print(level_order_traversal(root))  # 输出 [1, 2, 3, 4, 5]

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

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

相关文章

[C++]一、C++基础编程

G:\Cpp\2023版C教程 C语言程序设计 第一部分 基础篇 一、什么是C 1.1 C 简介 C 是一门非常经典的高级编程语言。顾名思义,C可以看做是C语言的增强版,在C的基础上扩展了更多的功能;最主要的扩展,就是面向对象和泛型编程。 因…

buuctf [MRCTF2020]hello_world_go

前言 学习笔记 这题签到! 64IDA打开。 查找字符串发现什么都没有。。。 没事 搜索main()【不知道go语言有没有,先搜索再说】 随便点开一个。 有flag格式,提交看看呗。 成了,签到。 flag{hello_world_gogogo} 题外话,…

Day18_Netty

文章目录 NettyIO 模型Java有哪些数据类型零拷贝深拷贝和浅拷贝的区别是什么?BIO、NIO、AIO的区别是什么?Netty 是什么?Netty 基于 NIO,那为啥不直接用 NIO 呢? / 为什么要用 Netty?Netty 应用场景了解么?那些开源项目用到了 Netty?Netty的核心组件是什么?请解释Netty…

Golang | Leetcode Golang题解之第371题两整数之和

题目&#xff1a; 题解&#xff1a; func getSum(a, b int) int {for b ! 0 {carry : uint(a&b) << 1a ^ bb int(carry)}return a }

汇编知识MOV,MRS,MSR,PUSH和POP指令

处理器做得最多的事情就是在处理器内部来回的进行数据传递 1) 将数据从一个寄存器传递到另一个寄存器中 2) 将数据从一个寄存器传递到特殊寄存器&#xff0c;例如CPSR,SPSR寄存器 3) 将立即数传递到寄存器。 数据传输常用的三个指令&#xff1a;MOV,MRS,MSR指令 常用的…

清华计算几何-线段求交与BO算法

单轴线段求交 给定单边轴下, N定线段&#xff0c;检查出相交的线段. 解法一: 暴力求解 遍历所有线段对&#xff0c;进行相交判断, 算法复杂度为O(n2) 解法二: LR扫描 把每条线段的头尾认定为L和R。对所有点进行排序&#xff0c;如果每两个点满足LL或者RR&#xff0c;则对应…

嵌入式UI开发-lvgl+wsl2+vscode系列:11、SSD202移植运行评估demo程序

一、前言 接下来我们根据开发板的LVGL指南移植lvgl的demo程序到开发板上&#xff0c;以及将一个评估的项目移植到开发板上&#xff0c;你将会发现移植lvgl到ssd2xx的板子上似乎很简单&#xff0c;但通过评估程序你将更加方便了解lvgl是否可以满足你的开发需求&#xff0c;除了…

使用了LSTM的数据预测

记录一下&#xff0c;这个是在national university of singapore,黄教授给我们布置的任务&#xff0c;做了一个北京的已知十年的打印量&#xff0c;预测100天的打印机大作业&#xff0c;我们使用了lstm模型&#xff0c;就是两层神经网络&#xff0c;同时dropout的加入为了防止过…

k8s跨节点后pod无法访问

场景 k8s在node1节点部署nginx后&#xff0c; 除node1外&#xff0c;主节点以及node2节点都无法正常访问nginx 并且主节点以及node2节点都无法ping通node1节点上的pod 网络插件为calico 并且也没有相关路由信息 解决方案 启动tunl0接口&#xff0c;因为calico需要使用tunl0网…

【解析几何笔记】8.向量的投影与内积

8. 向量的投影与内积 复习前面的知识&#xff1a;&#xff0c;若BCE三点共线&#xff0c;则 A E ⃗ ( 1 − s ) A B ⃗ s A C ⃗ , ( B , C , E ) μ ⇒ s μ 1 μ , 1 − s 1 1 μ \vec{AE}(1-s)\vec{AB}s\vec{AC},(B,C,E)\mu\Rightarrow s\frac{\mu}{1\mu},1-s\frac…

【学习笔记】时间序列模型(ARIMA)

文章目录 前言一、时间序列时间序列数据 二、ARIMA 模型大纲模型前提平稳性检验 差分整合移动平均自回归模型 ARIMA(p,q,d)自回归模型 (AR( p ))移动平均模型 (MA( q ))自回归移动平均模型(ARMA(p,q))差分自回归移动平均模型 ARIMA(p,d,q) 确定 p&#xff0c;q结果分析和模型检…

EVE-NG安装部署使用

EVE-NG安装部署使用 一、EVE的虚拟化安装1、下载EVE-NG(社区版)2、导入虚拟机-配置-登录二、EVE中设备的连接sercureCRT连接wireshark连接一、EVE的虚拟化安装 1、下载EVE-NG(社区版) 官网下载地址(科学上网): https://www.eve-ng.net/index.php/download/ 中文网下载…

运用Archimate为 智慧文旅搭建 数字化架构体系【系统架构】

ArchiMate是一种用于企业架构建模的开放、独立且详细的语言&#xff0c;它提供了一套丰富的概念和关系来描述、分析和可视化企业架构的不同领域。以下是ArchiMate建模的一些关键功能&#xff1a; 多视图建模&#xff1a;ArchiMate定义了23个示例视图&#xff0c;分为四类&#…

VMware-Ubuntu共享文件找不到

正常的流程我们实现设置共享目录 然后安装vmware-tool工具 我们先看一下vmware-tool的获取方式&#xff0c;系统安装好了以后&#xff0c;关闭系统将虚拟机设置改成图中配置&#xff0c;然后重启 鼠标右键会看到重新安装vmware-tool不再是灰色&#xff0c;点击重新安装 以1…

OpenCV几何图像变换(5)旋转和缩放计算函数getRotationMatrix2D()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算二维旋转的仿射矩阵。 该函数计算以下矩阵&#xff1a; [ α β ( 1 − α ) ⋅ center.x − β ⋅ center.y − β α β ⋅ center.x ( …

【TB作品】MSP430F149单片机,数字时钟万年历程序,滚动显示特效

一、 万年历 任务要求&#xff1a; 制作一个万年历&#xff0c;具有显示时间、日期、温度、湿度、闹钟功能。 1、OLED显示屏上显示日期和时钟&#xff08;显示到秒&#xff0c;时间可走动&#xff09;&#xff1b;&#xff08;20分&#xff09; 2、通过开发板上的温度传感器采集…

8月25日笔记

IOX的使用 iox是一款功能强大的端口转发&内网代理工具&#xff0c;该工具的功能类似于lcx和ew&#xff0c;但是iox的功能和性能都更加强大。 实际上&#xff0c;lcx和ew都是非常优秀的工具&#xff0c;但还是有地方可以提升的。在一开始使用这些工具的一段时间里&#xff…

前端常见**MS题 [3]

css部分 1、简单说明一下盒模型 CSS盒模型定义了盒的每个部分包含&#xff1a; margin, border, padding, content 。根据盒子大小的计算方式不同盒模型分成了两种&#xff0c;标准盒模型和怪异盒模型。 标准模型&#xff0c;给盒设置 width 和 height&#xff0c;实际设置的是…

C语言 | Leetcode C语言题解之第373题查找和最小的K对数字

题目&#xff1a; 题解&#xff1a; #define MIN(a, b) ((a) > (b) ? (b) : (a))int** kSmallestPairs(int* nums1, int nums1Size, int* nums2, int nums2Size, int k, int* returnSize, int** returnColumnSizes) {if (nums1Size 0 || nums2Size 0 || k < 0) {*ret…

Gerapy 分布式爬虫管理框架

什么是 Gerapy Gerapy 是一个基于 Scrapy 的分布式爬虫管理框架。它提供了一个图形化的用户界面&#xff0c;使得用户可以更方便地进行 Scrapy 项目的管理和调度。Gerapy 支持项目的创建、编辑、部署以及调度任务的管理。 功能作用 项目管理&#xff1a;Gerapy 允许用户通过 W…