二叉树
二叉树是树的特殊一种,具有如下特点:1、每个结点最多有两颗子树,结点的度最大为2。2、左子树和右子树是有顺序的,次序不能颠倒。3、即使某结点只有一个子树,也要区分左右子树。
特殊的二叉树
斜树
所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。这就是斜树,应用较少
满二叉树
所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树。就是完美圆满的意思,关键在于树的平衡。
根据满二叉树的定义,得到其特点为:
- 叶子只能出现在最下一层
- 非叶子结点度一定是2.
- 在同样深度的二叉树中,满二叉树的结点个数最多,叶子树最多。
完全二叉树
对一棵具有n个结点的二叉树按层序排号,如果编号为i的结点与同样深度的满二叉树编号为i结点在二叉树中位置完全相同,就是完全二叉树。满二叉树必须是完全二叉树,反过来不一定成立.
-
具有n的结点的完全二叉树的深度为log2n+1
-
如果有一颗有n个节点的完全二叉树的节点按层次序编号,对任一层的节点i(1<=i<=n)有
1.如果i=1,则节点是二叉树的根,无双亲,如果i>1,则其双亲节点为[i/2],向下取整
2.如果2i>n那么节点i没有左孩子,否则其左孩子为2i
3.如果2i+1>n那么节点没有右孩子,否则右孩子为2i+1
二叉树遍历
二叉树遍历:从树的根节点出发,按照某种次序依次访问二叉树中所有的结点,使得每个结点被访问仅且一次。
这里有两个关键词:访问和次序。
二叉树的三种访问方式
先序遍历:
按照根节点->左子树->右子树的顺序访问二叉树
先序遍历结果:A BDFE CGHI
思维过程:(1)先访问根节点A,
(2)A分为左右两个子树,因为是递归调用,所以左子树也遵循“先根节点-再左-再右”的顺序,所以访问B节点,
(3)然后访问D节点,
(4)访问F节点的时候有分支,同样遵循“先根节点-再左–再右”的顺序,
(5)访问E节点,此时左边的大的子树已经访问完毕,
(6)然后遵循最后访问右子树的顺序,访问右边大的子树,右边大子树同样先访问根节点C,
(7)访问左子树G,
(8)因为G的左子树没有,所以接下俩访问G的右子树H,
(9)最后访问C的右子树I
中序遍历:
按照左子树->根节点->右子树的顺序访问
中序遍历:(1)采用中序遍历左子树;(2)访问根节点;(3)采用中序遍历右子树
中序遍历结果:DBEF A GHCI
后序遍历
后序遍历:(1)采用后序递归遍历左子树;(2)采用后序递归遍历右子树;(3)访问根节点
后序遍历的结果:DEFB HGIC A
层次遍历
leetcode题目
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
1 5 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
思路
首先我们将root入list.
接着我们进入一个循环体,我们判断q。如果非空,我们通过在外层循环中设置一个临时list用来存储每一层的信息.我们就执行循环体中的内容。内存循环就变成了for _ in range(len(q)).外部循环条件,我们不可以写成while q:,因为当输入是[],这个时候q=[[]],python对这个结果的判定是True.
然后我们对len_q 遍历,将其加list,如果有左右节点分别加入
class Solution:
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
q= [root]
result =[]
while any(q):
tmp = list()
len_q= len(q)
for _ in range(len_q):
node= q.pop(0)
tmp.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
result.append(tmp)
return result