二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”
# 1.定义Node类,表示节点类
class Node:
# 初始化节点的信息
def __init__(self,item):
self.item = item # 元素域,数值域:存储区具体数据的
self.lchild = None # 链接域,地址域:左子节点
self.rchild = None # 链接域,地址域:右子节点
# 2.定义 BinaryTree类,表示:二叉树类
class BinaryTree:
# 2.1指定二叉树的根节点
def __init__(self,root=None):
self.root = root # 充当根节点
# 2.2 添加元素
def add(self,item):
"""
自定义二叉树添加元素
:param item: 要添加的数据
:return:
"""
# 1.判断根节点是否为空,若为空,直接将当前元素设置为:根节点,程序结束
if self.root == None:
self.root = Node(item)
return
# 2.走到这里,说明根节点不为空,我们准备列表,用于存储: 二叉树中所有的节点。
queue = []
queue.append(self.root)
# 3. 通过while True, 不断的获取到二叉树中的节点.
while True:
cur_node = queue.pop(0) # 获取节点的.
# 4. 判断当前节点的 左子树(左子节点)是否为空.
if cur_node.lchild == None:
# 4.1 若为空, 则将: 新节点添加为当前节点的 左子树
cur_node.lchild = Node(item)
return
else:
# 4.2 如果不为空, 则将: 当前节点的左子树加到 队列中.
queue.append(cur_node.lchild)
# 5. 判断当前节点的 右子树(右子节点)是否为空.
if cur_node.rchild == None:
# 5.1 若为空, 则将: 新节点添加为当前节点的 右子树
cur_node.rchild = Node(item)
return
else:
# 5.2 如果不为空, 则将: 当前节点的右子树加到 队列中.
queue.append(cur_node.rchild)
# 2.3 遍历广度优先
def breadth_travle(self):
# 1. 判断根节点是否为空.
if self.root == None:
return
# 2. 创建队列(queue), 用于存储: 二叉树的元素.
queue = []
queue.append(self.root) # 添加根节点到队列中.
# 3. 循环获取元素(节点), 只要队列不为空(说明还有二叉树节点), 就一直遍历.
while len(queue) > 0:
# 3.1 走这里, 说明队列有数据, 我们从(队头)获取元素.
node = queue.pop(0)
# 3.2 打印当前节点的内容.
print(node.item, end=' ')
# 3.3 判断当前节点是否有左子树, 有就添加到 队列中.
if node.lchild is not None:
queue.append(node.lchild)
# 3.4 判断当前节点是否有右子树, 有就添加到 队列中.
if node.rchild is not None:
queue.append(node.rchild)
# 2.4 遍历, 深度优先 => 前序, 即: 根, 左, 右
def preorder_travle(self, root): # root表示节点
# 1. 判断根节点是否不为空, 不为空, 就按照 根,左,右 顺序逐个获取.
if root is not None:
# 2. 根
print(root.item, end = ' ')
# 3. 左, 递归获取.
self.preorder_travle(root.lchild)
# 4. 右, 递归获取.
self.preorder_travle(root.rchild)
# 2.5 遍历, 深度优先 => 中序, 即: 左, 根, 右
def inorder_travle(self, root): # root表示节点
# 1. 判断根节点是否不为空, 不为空, 就按照 左, 根, 右 顺序逐个获取.
if root is not None:
# 2. 左, 递归获取.
self.inorder_travle(root.lchild)
# 3. 根
print(root.item, end = ' ')
# 4. 右, 递归获取.
self.inorder_travle(root.rchild)
# 2.6 遍历, 深度优先 => 后序, 即: 左, 右, 根
def postorder_travle(self, root): # root表示节点
# 1. 判断根节点是否不为空, 不为空, 就按照 左, 右, 根 顺序逐个获取.
if root is not None:
# 2. 左, 递归获取.
self.postorder_travle(root.lchild)
# 3. 右, 递归获取.
self.postorder_travle(root.rchild)
# 4. 根
print(root.item, end = ' ')
# 3.测试代码1,创建节点和二叉树
def test1():
# 3.1 创建节点
node = Node('乔峰')
# 3.2 打印节点
print(node.item)
# 3.3 创建二叉树对象
bt = BinaryTree(node)
print(bt) # 二叉树
print(bt.root) # 二叉树的根节点
print(bt.root.item) # 二叉树的根节点的元素域
# 4 测试代码2 :演示队列,先进先出
def test2():
# 4.1创建队列.
queue = []
# 4.2 往队列中(从队尾)添加元素
queue.append('A')
queue.append('B')
queue.append('C')
# 4.3 从队列中(从队头)获取元素。
print(queue.pop(0))
print(queue.pop(0))
print(queue.pop(0))
# 5.测试3:测试添加元素到二叉树中, 及广度优先遍历
def test3():
# 5.1 创建二叉树
bt = BinaryTree()
# 5.2 添加元素
bt.add('A')
bt.add('B')
bt.add('C')
bt.add('D')
bt.add('E')
bt.add('F')
bt.add('G')
bt.add('H')
bt.add('I')
bt.add('J')
bt.add('K')
# 5.3 广度优先遍历, 查看结果.
bt.breadth_travle()
# 6. 测试代码4: 测试添加元素到二叉树中, 及 深度优先遍历.
def test4():
# 5.1 创建二叉树.
bt = BinaryTree()
# 5.2 添加元素.
bt.add('0')
bt.add('1')
bt.add('2')
bt.add('3')
bt.add('4')
bt.add('5')
bt.add('6')
bt.add('7')
bt.add('8')
bt.add('9')
# 5.3 广度优先遍历, 查看结果.
# bt.breadth_travle() # 广度优先: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
# 5.4 深度优先, 前序
print('前序: ', end = '')
bt.preorder_travle(bt.root) # 前序: 0 1 3 7 8 4 9 2 5 6
print()
# 5.5 深度优先, 中序
print('中序: ', end = '')
bt.inorder_travle(bt.root) # 中序: 7 3 8 1 9 4 0 5 2 6
print()
# 5.6 深度优先, 后序
print('后序: ', end = '')
bt.postorder_travle(bt.root) # 后序: 7 8 3 9 4 1 5 6 2 0
# 6.main函数
if __name__ == '__main__':
#test1()
#test2()
#test3()
test4()