Python与数据结构[3] -> 树/Tree[0] -> 二叉树及遍历二叉树的 Python 实现
二叉树 / Binary Tree
二叉树是树结构的一种,但二叉树的每一个节点都最多只能有两个子节点。
Binary Tree:
00
|_____
| |
00 00
|__ |__
| | | |
00 00 00 00
对于二叉树的遍历,主要有以下三种基本遍历方式:
- 先序遍历:先显示节点值,再显示左子树和右子树
- 中序遍历:先显示左子树,再显示节点值和右子树
- 后序遍历:先显示左子树和右子树,再显示节点值
下面将用代码构建一个二叉树,并实现三种遍历方式,
完整代码
class TreeNode:
def __init__(self, val=None, lef=None, rgt=None):
self.value = val
self.left = lef
self.right = rgt def __str__(self):
return str(self.value) class BinaryTree:
"""
Binary Tree:
00
|_____
| |
00 00
|__ |__
| | | |
00 00 00 00
"""
def __init__(self, root=None):
self._root = root def __str__(self):
return '\n'.join(map(lambda x: x[1]*4*' '+str(x[0]), self.pre_traversal())) def pre_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
x.append((node, depth))
if node and node.left is not None:
_traversal(node.left)
if node and node.right is not None:
_traversal(node.right)
depth -= 1
return x
return _traversal(root) def in_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
if node and node.left is not None:
_traversal(node.left)
x.append((node, depth))
if node and node.right is not None:
_traversal(node.right)
depth -= 1
return x
return _traversal(root) def post_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
if node and node.left is not None:
_traversal(node.left)
if node and node.right is not None:
_traversal(node.right)
x.append((node, depth))
depth -= 1
return x
return _traversal(root) @property
def max_depth(self):
return sorted(self.pre_traversal(), key=lambda x: x[1])[-1][1] def show(self, tl=None):
if not tl:
tl = self.pre_traversal()
print('\n'.join(map(lambda x: x[1]*4*' '+str(x[0]), tl))) def make_empty(self):
self.__init__() def insert(self, item):
if self._root is None:
self._root = TreeNode(item)
return def _insert(item, node):
if not node:
return TreeNode(item)
if node.left is None:
node.left = _insert(item, node.left)
elif node.right is None:
node.right = _insert(item, node.right)
else:
if len(self.pre_traversal(node.left)) <= len(self.pre_traversal(node.right)):
node.left = _insert(item, node.left)
else:
node.right = _insert(item, node.right)
return node
self._root = _insert(item, self._root) if __name__ == '__main__':
bt = BinaryTree()
print('\nBinary Tree:')
'''
0
|_____
| |
1 2
|__ |__
| | | |
3 5 4 6
'''
for i in range(7):
bt.insert(i)
bt.show()
print('\n------Pre-traversal-------')
print(bt) print('\n------Post-traversal------')
bt.show(bt.post_traversal())
print('\n-------In-traversal-------')
bt.show(bt.in_traversal()) bt.make_empty()
print('\n-------Empty-tree-------')
print(bt)
分段解释
首先定义树节点,包含3个属性(指针引用),分别为:当前值,左子树节点,右子树节点
class TreeNode:
def __init__(self, val=None, lef=None, rgt=None):
self.value = val
self.left = lef
self.right = rgt def __str__(self):
return str(self.value)
构建一个二叉树类,构造函数中包含一个根节点属性,
class BinaryTree:
"""
Binary Tree:
00
|_____
| |
00 00
|__ |__
| | | |
00 00 00 00
"""
def __init__(self, root=None):
self._root = root
重定义__str__方法,在打印树时,依据树的深度添加tab显示,类似于文件目录(文件分级目录原本便是由树实现的)的显示方式
def __str__(self):
return '\n'.join(map(lambda x: x[1]*4*' '+str(x[0]), self.pre_traversal()))
定义先序遍历方法,通过递归的方式进行实现,优先显示当前节点
def pre_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
x.append((node, depth))
if node and node.left is not None:
_traversal(node.left)
if node and node.right is not None:
_traversal(node.right)
depth -= 1
return x
return _traversal(root)
定义中序遍历方法,与先序遍历基本相同,只是处理当前节点的顺序在左子树之后,右子树之前,
def in_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
if node and node.left is not None:
_traversal(node.left)
x.append((node, depth))
if node and node.right is not None:
_traversal(node.right)
depth -= 1
return x
return _traversal(root)
定义后序遍历方法,处理当前节点的顺序在左子树和右子树之后,
def post_traversal(self, root=None):
if not root:
root = self._root
x = []
depth = -1 def _traversal(node):
nonlocal depth
depth += 1
if node and node.left is not None:
_traversal(node.left)
if node and node.right is not None:
_traversal(node.right)
x.append((node, depth))
depth -= 1
return x
return _traversal(root)
再定义一些树的基本方法,显示树的时候,优先采用先序遍历显示,
@property
def max_depth(self):
return sorted(self.pre_traversal(), key=lambda x: x[1])[-1][1] def show(self, tl=None):
if not tl:
tl = self.pre_traversal()
print('\n'.join(map(lambda x: x[1]*4*' '+str(x[0]), tl))) def make_empty(self):
self.__init__()
最后定义二叉树的插入方法,插入方式尽量保证二叉树的平衡,插入顺序为当前节点->左->右,当左右节点都不为空时,则递归插入左子树和右子树中,深度较小的那一棵树。
def insert(self, item):
if self._root is None:
self._root = TreeNode(item)
return def _insert(item, node):
if not node:
return TreeNode(item)
if node.left is None:
node.left = _insert(item, node.left)
elif node.right is None:
node.right = _insert(item, node.right)
else:
if len(self.pre_traversal(node.left)) <= len(self.pre_traversal(node.right)):
node.left = _insert(item, node.left)
else:
node.right = _insert(item, node.right)
return node
self._root = _insert(item, self._root)
定义完二叉树类后,对二叉树进行构建,插入元素并利用三种遍历方式显示二叉树。
if __name__ == '__main__':
bt = BinaryTree()
print('\nBinary Tree:')
'''
0
|_____
| |
1 2
|__ |__
| | | |
3 5 4 6
'''
for i in range(7):
bt.insert(i)
bt.show()
print('\n------Pre-traversal-------')
print(bt) print('\n------Post-traversal------')
bt.show(bt.post_traversal())
print('\n-------In-traversal-------')
bt.show(bt.in_traversal()) bt.make_empty()
print('\n-------Empty-tree-------')
print(bt)
三种遍历方式显示结果如下
Binary Tree:
0
1
3
5
2
4
6 ------Pre-traversal-------
0
1
3
5
2
4
6 ------Post-traversal------
3
5
1
4
6
2
0 -------In-traversal-------
3
1
5
0
4
2
6 -------Empty-tree-------
None
Python与数据结构[3] -> 树/Tree[0] -> 二叉树及遍历二叉树的 Python 实现的更多相关文章
- Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现
AVL 平衡树和树旋转 目录 AVL平衡二叉树 树旋转 代码实现 1 AVL平衡二叉树 AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实 ...
- Python与数据结构[3] -> 树/Tree[1] -> 表达式树和查找树的 Python 实现
表达式树和查找树的 Python 实现 目录 二叉表达式树 二叉查找树 1 二叉表达式树 表达式树是二叉树的一种应用,其树叶是常数或变量,而节点为操作符,构建表达式树的过程与后缀表达式的计算类似,只不 ...
- Python与数据结构[4] -> 散列表[0] -> 散列表与散列函数的 Python 实现
散列表 / Hash Table 散列表与散列函数 散列表是一种将关键字映射到特定数组位置的一种数据结构,而将关键字映射到0至TableSize-1过程的函数,即为散列函数. Hash Table: ...
- 用Python实现数据结构之树
树 树是由根结点和若干颗子树构成的.树是由一个集合以及在该集合上定义的一种关系构成的.集合中的元素称为树的结点,所定义的关系称为父子关系.父子关系在树的结点之间建立了一个层次结构.在这种层次结构中有一 ...
- 数据结构(二) 树Tree
五.树 树的定义 树的逻辑表示:树形表示法.文氏图表示法.凹入表示法.括号表示法. 结点:表示树中的元素,包括数据项及若干指向其子树的分支. 结点的度:结点拥有的子树树:树的度:一 ...
- LeetCode 965. 单值二叉树 (遍历二叉树)
题目链接:https://leetcode-cn.com/problems/univalued-binary-tree/ 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树. 只有给定的树是 ...
- 《程序员代码面试指南》第三章 二叉树问题 遍历二叉树的神级方法 morris
题目 遍历二叉树的神级方法 morris java代码 package com.lizhouwei.chapter3; /** * @Description:遍历二叉树的神级方法 morris * @ ...
- 用python讲解数据结构之树的遍历
树的结构 树(tree)是一种抽象数据类型或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合 它具有以下的特点: ①每个节点有零个或多个子节点: ②没有父节点的节点称为根节点: ③ ...
- Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现
栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...
随机推荐
- 【电影影评】梦之安魂曲-败给了BGM和豆瓣影评
首先,这部电影豆瓣8.7分,一般来说,豆瓣的打分是比较准确的.能反映一个片子的质量,而较少受到环境的影响.但是这种关系当然也不全对,比如某些片子可能特别让某一种人喜欢(如退役军人和军旅题材),而在某些 ...
- [BZOJ4212]神牛的养成计划
[BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ...
- [NOIP2017]列队 线段树
---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当 ...
- BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】
题目链接 BZOJ4012 题解 Mychael并没有A掉,而是T掉了 讲讲主要思路 在点分树上每个点开两棵\(splay\), 平衡树\(A\)维护子树中各年龄到根的距离 平衡树\(B\)维护子树中 ...
- BZOJ3211 花神游历各国 【树状数组 + 并查集】
题目 输入格式 输出格式 每次x=1时,每行一个整数,表示这次旅行的开心度 输入样例 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 2 3 1 1 4 输出样例 101 11 1 ...
- BZOJ3529 [Sdoi2014]数表 【莫比乌斯反演】
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2151 Solved: 1080 [Submit][Status ...
- 【CF MEMSQL 3.0 D. Third Month Insanity】
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- [poj 3693]后缀数组+出现次数最多的重复子串
题目链接:http://poj.org/problem?id=3693 枚举长度L,看长度为L的子串最多能重复出现几次,首先,能出现1次是肯定的,然后看是否能出现两次及以上.由抽屉原理,这个子串出现次 ...
- HDU 1698 Just a Hook(线段树
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Create a conditional DNS forwarder on our domain.com to Amazon default DNS provider
Backgroup: I have an AWS Managed Active Directory(domain.com). I created a DHCP options set to my d ...