【Python学习-二叉树】【剑指offer】之从上往下打印二叉树、二叉搜索树后序遍历序列、 二叉树中和为某一值的路径
从上往下打印二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
分析
一层一层的遍历,每一层都会有值,所以专门准备一个空列表存放没一层的值,到下一层时,自动清空,当这一层的值为空时,说明循环结束了,每次遍历一层时,1、保存该层的值 2、改成下一层的值用另一个空列表保存,自动清空。详情见代码分析。
代码
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回从上到下每个节点值列表,例:[1,2,3]
def PrintFromTopToBottom(self, root):
# write code here
if not root:
return []
res = []#最终的返回列表
# 先将root中的成员拷贝到新定义的 newroot中
newroot = [root] # 准备一个列表专门保存没一层的值,自动清空
while newroot: # 当下一层的值为空时 说明遍历完了
nextlist = [] # 定义的下一个列表,每一次循环都要清空
for i in newroot:
# 存在左右孩子的话就插到nextlist 列表中
if i.left:
nextlist.append(i.left)
if i.right:
nextlist.append(i.right) # 用来保存下一层的值
res.append(i.val) # 本层的值添加到准备的专门保存的列表
newroot = nextlist #
return res
二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
分析
先介绍一下二叉搜索树:
二叉搜索树的特点:对于树中的每个节点X,它的左子树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值。
根据这个性质,对一个二叉树进行中序遍历,如果是单调递增的,则可以说明这个树是二叉搜索树。
根据后序遍历,可以知道数组的最后一个元素为根,又有二叉搜索树的特点,左节点<根节点<右节点,知道根节点后,可以和数组前面的元素比较大小,这样可以分出左右子树,然后可以使用递归,对左右子树根据根又去分左右子树。详细见代码分析。
代码
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
length = len(sequence) # 数组为空False
if length == 0:
return False
if length == 1: # 数组只有一个根元素,则是真的后序遍历
return True
root = sequence[-1] # 除开上面的情况,数组最后一个元素为根
left = 0
while sequence[left] < root: # 找到分开左右子树的位置
left += 1
for j in range(left, length-1): # 从这个位置开始到后面的元素应该是都要大于根节点,如果小于 那么就不是后序遍历
if sequence[j] < root:
return False # 这种情况会返回False
# 到这里为止,这一层的就算遍历完了,但是分开的左右子树还没有遍历,是否有这种规律,所以,对左右子树继续调用,直到每一层的数组为0或1
return self.VerifySquenceOfBST(sequence[:left]) or self.VerifySquenceOfBST(sequence[left:length-1]) # 最后的可能情况,左0右1 左1右0 左1右1 不可能0 0 所以这里是或 0 1 也是正确的,要返回True 则必须用或
二叉树中和为某一值的路径
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)–这个条件答案没有考虑
分析
见代码分析。
代码
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
if not root:
return []
tmp = [] # 准备空列表用来保存路径
if not root.left and not root.right and root.val == expectNumber:
return [[root.val]] # 当访问到最后的节点,无左右节点时,就直接返回值即可
else: # 如果有左右节点的话 那么就要递归调用了
left = self.FindPath(root.left,expectNumber-root.val) # 每向下一层时,减掉根的值,判断是否相等即可
right = self.FindPath(root.right,expectNumber-root.val)
for item in left+right: # 这一层的每一个值都要算一种可能
tmp.append([root.val]+item)
return tmp