二叉树 / Binary Tree


二叉树是树结构的一种,但二叉树的每一个节点都最多只能有两个子节点。

Binary Tree:
00
|_____
| |
00 00
|__ |__
| | | |
00 00 00 00

对于二叉树的遍历,主要有以下三种基本遍历方式:

  1. 先序遍历:先显示节点值,再显示左子树和右子树
  2. 中序遍历:先显示左子树,再显示节点值和右子树
  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 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 实现的更多相关文章

  1. Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现

    AVL 平衡树和树旋转 目录 AVL平衡二叉树 树旋转 代码实现 1 AVL平衡二叉树 AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实 ...

  2. Python与数据结构[3] -> 树/Tree[1] -> 表达式树和查找树的 Python 实现

    表达式树和查找树的 Python 实现 目录 二叉表达式树 二叉查找树 1 二叉表达式树 表达式树是二叉树的一种应用,其树叶是常数或变量,而节点为操作符,构建表达式树的过程与后缀表达式的计算类似,只不 ...

  3. Python与数据结构[4] -> 散列表[0] -> 散列表与散列函数的 Python 实现

    散列表 / Hash Table 散列表与散列函数 散列表是一种将关键字映射到特定数组位置的一种数据结构,而将关键字映射到0至TableSize-1过程的函数,即为散列函数. Hash Table: ...

  4. 用Python实现数据结构之树

    树 树是由根结点和若干颗子树构成的.树是由一个集合以及在该集合上定义的一种关系构成的.集合中的元素称为树的结点,所定义的关系称为父子关系.父子关系在树的结点之间建立了一个层次结构.在这种层次结构中有一 ...

  5. 数据结构(二) 树Tree

    五.树 树的定义   树的逻辑表示:树形表示法.文氏图表示法.凹入表示法.括号表示法.         结点:表示树中的元素,包括数据项及若干指向其子树的分支. 结点的度:结点拥有的子树树:树的度:一 ...

  6. LeetCode 965. 单值二叉树 (遍历二叉树)

    题目链接:https://leetcode-cn.com/problems/univalued-binary-tree/ 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树. 只有给定的树是 ...

  7. 《程序员代码面试指南》第三章 二叉树问题 遍历二叉树的神级方法 morris

    题目 遍历二叉树的神级方法 morris java代码 package com.lizhouwei.chapter3; /** * @Description:遍历二叉树的神级方法 morris * @ ...

  8. 用python讲解数据结构之树的遍历

    树的结构 树(tree)是一种抽象数据类型或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合 它具有以下的特点: ①每个节点有零个或多个子节点: ②没有父节点的节点称为根节点: ③ ...

  9. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

随机推荐

  1. 感觉自己应该重新读一次Javascript

    我自己也有一本Javascript书籍,是自己上大学的时候学校给提供的,现在,我依旧带着这本书.我决定要把这本书在重新温习一下.然后,开启下面的Javascript之旅.这是我看到博客园一位园友写的, ...

  2. P3032 [USACO11NOV]二进制数独Binary Sudoku

    题目描述 Farmer John's cows like to play an interesting variant of the popular game of "Sudoku" ...

  3. Hibernate高级应用

    数据模型与领域模型的关系 领域模型是一个分析模型,它帮助需求分析人员.用户认识现实业务的工具,描述的是业务中设计的试题及其相互之间的关系,它是需求分析的产物.领域模型是需求分析人员与用户交流的有力工具 ...

  4. 【题解】CQOI2017老C的方块

    网络流真的是一种神奇的算法.在一张图上面求感觉高度自动化的方案一般而言好像都是网络流的主阵地.讲真一开始看到这道题也有点懵,题面很长,感觉很难的样子.不过,仔细阅读了题意之后明白了:我们所要做的就是要 ...

  5. BZOJ1558 [JSOI2009]等差数列 【线段树】

    题目链接 BZOJ1558 题解 等差数列,当然是差分一下 差分值相同的连续位置形成等差数列,我们所选的两个等差数列之间可以有一个位置舍弃 例如: \(1 \; 2 \; 3 \; 6 \; 8 \; ...

  6. 12.25模拟赛T3

    可以发现,答案O(根号)(因为链上答案最大,n/2,n/3...根号种) 每次求答案要二分 优秀的做法是: 对于小于根号n的暴力nlogn找,可能二分到同一个mid,记忆化一下最小的tot值 对于大于 ...

  7. HDU 5666 快速乘

    Segment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  8. ng websocket

    ng使用websocket 1.安装依赖库npm install ws --save 2.安装类型定义文件 npm install @types/ws --save 3.编写服务 import { I ...

  9. Virtualization solutions on Linux systems - KVM and VirtualBox

    Introduction Virtualization packages are means for users to run various operating systems without &q ...

  10. (转)什么是JSON+如何处理JSON字符串

    仍然是crifan的好文: http://www.crifan.com/summary_what_is_json_and_how_to_process_json_string/ . . . .