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 链表栈 链表栈是以单链 ...
随机推荐
- [HAOI2007]理想的正方形 st表 || 单调队列
~~~题面~~~ 题解: 因为数据范围不大,而且题目要求的是正方形,所以这道题有2种解法. 1,st表. 这种解法暴力好写好理解,但是较慢.我们设st[i][j][k]表示以(i, j)为左端点,向下 ...
- POJ3660:Cow Contest(Floyd传递闭包)
Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16941 Accepted: 9447 题目链接 ...
- Eclipse来push,fetch,rebase代码
如何与项目里的其他人一起合作项目,提交代码并更新呢?这里提出我比最近用到的两种工具:一种是Eclipse,另外一个是SourceTree.个人推荐从事Java开发的话,可以用Eclipse.当然,还有 ...
- npm安装node-sass失败,EACCES: permission denied
增加--unsafe-perm,即 sudo npm install node-sass --unsafe-perm --save-dev 成功安装node-sass
- jquery学习总计
1,jquery的基础语法 $(selector).action(); 选择器(selector)查询和查找html元素,action()执行对函数的操作. 2.选择器 id,类,类型,属性,属性值等 ...
- sublime JSX Html 标签补全
Preferences -> Package Settings -> Emmet ->key bindings – user { "keys": ["t ...
- 搭建jfinal+maven框架
1.创建一个maven web项目. 2.添加引用包 <dependency> <groupId>com.jfinal</grou ...
- Hibernate 三种状态变化 与 sql 语句的关系
前言:在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的.对于理解hibernate,JVM和sql的关系有更好的 ...
- Nginx的client_header_buffer_size和large_client_header_buffers学习
之前看到有人写的一篇关于nginx配置中large_client_header_buffers的问题排查的文章,其中提到: large_client_header_buffers 虽然也可以在serv ...
- HDU1272---(并查集)简单应用
http://acm.hdu.edu.cn/showproblem.php?pid=1272 小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memor ...