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 = name
self.type = type
self.children = [] # 初始化为空列表,目录节点可以包含子节点
self.parent = None # 父节点初始化为 None
def __repr__(self):
return self.name
class 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.parent
elif component and component != '/':
# 如果路径部分是有效的目录名,则查找该目录
found = False
for child in node.children:
if child.name == component + '/':
node = child # 找到目标目录,更新当前节点
found = True
break
if 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 = data
self.lchild = None
self.rchild = None
**实现这棵二叉树**
class BiTreeNode:
def __init__(self, data):
self.data = data
self.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 = f
root = e
print(root.lchild.rchild.data)
3.1 二叉树的遍历
二叉树的前序遍历
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,
二叉树的中序遍历
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,
二叉树的后序遍历
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
二叉树的层次遍历
from collections import deque
def 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,