1. 二叉树基本知识
二叉树
树是无环的通路,是由节点和节点之间的“枝”构成。一个包含n个节点的二叉树,包含n-1条枝,树底部的节点称为“树根”,树上面没有枝延伸的节点为“叶子”。上层节点被称为“父节点”,下层的节点为“子节点”。树的层数k被称为树的深度。
如果一个树中,每个节点最多只有两个子节点的时候,一棵树为二叉树。根据结构特征,又可以将树分为满二叉树、完全二叉树等。满二叉树的结果如下,其特点为每个非叶子节点都有2个子节点,
图1. 满二叉树
一个k层满二叉树的包含的节点数为。完美二叉树中,对一颗具有n个结点的二叉树按层编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。参考深入学习二叉树(一) 二叉树基础 - 简书。如下,
图2. 完全二叉树
完全二叉树的特点如下,
1)叶子结点只能出现在最下层和次下层。
2)最下层的叶子结点集中在树的左部。
3)倒数第二层若存在叶子结点,一定在右部连续位置。
4)如果结点度为1,则该结点只有左孩子,即没有右子树。
5)同样结点数目的二叉树,完全二叉树深度最小。
注:满二叉树一定是完全二叉树,但反过来不一定成立。
二叉树的遍历
根据在什么时候访问中间节点,遍历可以分为前序遍历、中序遍历和后序遍历,其中的“序”针对的都是对左中右中的中间节点。参考关于二叉树,你该了解这些!。
以下面的二叉树为例,
图2. 二叉树的遍历
前序遍历:1245367
中序遍历:4251637
后序遍历:4526731
对于前序遍历来说,相当于从根节点开始遍历;中序遍历和后序遍历,先找到左节点,左节点→中间节点→右节点;后序遍历,先访问左右节点,再访问中间节点,左节点→右节点→中间节点。不论是哪种访问顺序,都是先访问左节点,再访问右节点。
以后序遍历为例,
(1)根节点为1,1的左节点为2;
(2)2的左节点为4;
(3)4没有左节点,因此4为第一个被访问的节点,对应的右节点为5;
(4)5没有左节点,因此5为第二个被访问的节点;
(5)访问中间节点2;
(6)2(左节点)对应的右节点为3,其左节点为6;
(7)6没有左节点,因此6为下一个被访问的节点;
(8)6对应的右节点为7,没有左右节点,访问7;
(9)对应的中间节点为3,访问3;
(10)对应的中间节点为根节点,访问1,结束。
从以上过程可以看出,该遍历过程为一个递归的过程。前序遍历为从根部遍历;中序遍历为从左向右遍历;后序遍历为从左向右遍历。
2. 二叉树遍历的代码实现
LeetCode144
LeetCode145
LeetCode94
代码如下,
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def set_left(self, left):
self.left = left
def set_right(self, right):
self.right = right
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
r = []
if root is not None:
r.append(root.val)
if root.left != None:
r.extend(self.preorderTraversal(root.left))
if root.right != None:
r.extend(self.preorderTraversal(root.right))
return r
else:
return
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
r = []
if root is not None:
if root.left != None:
r.extend(self.inorderTraversal(root.left))
r.append(root.val)
if root.right != None:
r.extend(self.inorderTraversal(root.right))
return r
else:
return
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
r = []
if root is not None:
if root.left != None:
r.extend(self.postorderTraversal(root.left))
if root.right != None:
r.extend(self.postorderTraversal(root.right))
r.append(root.val)
return r
else:
return
if __name__ == '__main__':
root = [1, 2, 3]
node1 = TreeNode(1)
node2 = TreeNode(2)
node3 = TreeNode(3)
node1.set_right(node2)
node2.set_left(node3)
sol = Solution()
# r = sol.preorderTraversal(node1)
r = sol.inorderTraversal(node1)
print(r)