数据结构与算法05(python实现)__二叉树
二叉树的基本概念
二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)
二叉树的性质(特性)
性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
性质2: 深度为k的二叉树至多有2^k - 1个结点(k>0)
性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)
(1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
(2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
二叉树的节点表示以及树的创建
通过使用Node类中定义三个属性,分别为elem本身的值,还有lchild左孩子和rchild右孩子
# 二叉树的实现: # 1.保存数据,基于链表,需要获取链表的节点 # 2.实现的操作 class Node(object): '''节点类''' def __init__(self, item=None): # 不同于单链表,链接区多为left和right self.item = item self.lchild = None # 左子节点 self.rchild = None # 右子节点 class BinaryTree(object): '''二叉树''' def __init__(self, root=None): '''保存数据,只要有根节点,即可找到其他节点''' self.root = root # 此处不要设为私有 def add(self, item): '''增加节点''' # 使用层次(广度)搜索 # 基于队列先进先出实现,保证每次只判断一个节点 new_node = Node(item) # 特殊情况,空tree if self.root is None: self.root = new_node return # 创建一个队列(用列表代替) queue = [] # 先进,每次都从根节点搜索,直到找到合适的位置放元素 queue.append(self.root) # 这里也可以while True,因为下面总会走到return(总会有某一节点的左右子节点为None的时候) while queue: # 只要队列不为空,说明没有搜索完 # 先出,保证每次只判断一个节点 node = queue.pop(0) if node.lchild is None: # 说明该node左子节点为空,优先增加新节点 node.lchild = new_node return # add成功,结束搜索tree的过程 elif node.rchild is None: # 该node右子节点为空,次之在此增加新节点 node.rchild = new_node return # add成功,结束搜索tree的过程 else: # 到此说明,该节点左右子节点都满了, # 将此node的左右子节点加入队列中,进而再判断这些加入的子节点 queue.append(node.lchild) queue.append(node.rchild) def breadth_travel(self): '''广度(层次)遍历二叉树''' if self.root is None: print('') return # 以下说明非空,利用队列进行遍历,每次只操作一个节点(和其对于的左右节点,如果有的话) queue = [] queue.append(self.root) while queue: node = queue.pop(0) # 打印当前node的item print(node.item, end=' ') if node.lchild is not None: # 该node左子节点非空,加入队列中 queue.append(node.lchild) if node.rchild is not None: # 该node右子节点非空,加入队列中 queue.append(node.rchild) print('') # 以下是三种深度遍历二叉树 @classmethod def preorder(cls, root): # 需要传入根节点,根据根节点进行遍历 '''先序遍历 根 左 右''' if root is None: # 空tree # print('') return # 递归终止 # 以下说明非空tree print(root.item, end=' ') cls.preorder(root.lchild) cls.preorder(root.rchild) @classmethod def inorder(cls, root): # 需要传入根节点,根据根节点进行遍历 '''中序遍历 左 根 右''' if root is None: # 空tree return # 递归终止 cls.inorder(root.lchild) print(root.item, end=' ') cls.inorder(root.rchild) @classmethod def postorder(cls, root): """后序遍历 左 右 根""" if root is None: return cls.postorder(root.lchild) cls.postorder(root.rchild) print(root.item, end=" ") if __name__ == '__main__': tree = BinaryTree() for i in range(10): tree.add(i) # tree.breadth_travel() tree.preorder(tree.root) print('') tree.inorder(tree.root) print('') tree.postorder(tree.root)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)