二叉树的右侧
问题:
小明和小伙伴去摘柠檬,小明负责摘树的右侧的柠檬,假如柠檬树的每个树干只有两个树枝、一个树枝、零个树枝三种可能,那么一棵树可以被看作一颗二叉树,小明摘树的右侧,让我们算一下,它可以摘到哪些柠檬。
解决问题
这个问题可以用二叉树来表示,如图:
树1:
树2:
对于树1来说,小明可以摘到的柠檬为1、3、6、7这四个柠檬。
对于树2来说,小明可以摘到的柠檬为1、3、5、7,也就是说要摘下站在树右边能看到的柠檬。
注意:二叉树是每个节点最多有两个子树的树结构
此时,本题的问题就变成了给定一颗二叉树,想想你自己站在该二叉树的右侧,按照从根节点到低端叶子节点的顺序,找出可以获取的节点的值的问题。
为了表示这样的树,需要定义一个二叉树的结构 ,代码如下:
class TreeNode(object):#定义二叉树的根节点为TreenNode
def __init__(self,x):
self.val = x #定义二叉树的每个元素的值,这里表示柠檬的编号
self.left = None #定义二叉树的每个元素的左子树
self.right = None #定义二叉树的每个元素的右子树
根据前面的分析,为了找出二叉树右侧的节点的值,我们需要一层一层地取出每一层的数据,然后把每层的数据放入最终结果中。我们为每个节点设定一个层级,比如根节点的层级是第1层,根节点的子节点的层级是第2层,依次递增。
二叉树的层次结构:
,这个题目是遍历问题,或者说是求二叉树广度优先遍历的一种变形,我们只需要薄层每一层最右边的数字即可。
因为是广度优先遍历算法,一定要用到队列,使用队列来保存待处理的节点。首先处理根节点,存储根节点的值,同时建立存放结果的列表,代码框架如下:
def rightSide(root):
result = [] #存放结果数据
queue = [root] #队列存放待处理数据
while len(queue) > 0:
#队列不为空时,以此取出数据做处理
return result
使用广度优先遍历算法的时候,需要先取出每层的节点,然后处理该节点,之后把下一次的左右节点都存放入队列,以此类推,到队列为空,处理就完毕了。
核心问题就是如何找到每层的最后一个节点,我们可以在处理每层数据的是时候记录一下当前层的节点数N,那么本层最后一个节点就是当前队列里的第N个数据,在寻找每层最后一个元素的同时,把每个节点的左右节点加入队列,一直到这一层的所有元素都分析完为止。对于每层节点的分析,使用一个for循环来处理。整个程序在队列为空时结束:
while len(queue) > 0: #队列不为空时,依次取出数据做处理
length = len(queue) #先保存本层的数量
for i in range(length): #以此处理每一行
node = queue.pop() #取出队列头的点
if i == length - 1: #当该点时最后一个点的时候把他加入结果数组里
result.append(node.val)
if node.left != None:
queue.append(node.left)# 把左节点加入队列
if node.right != None:
queue.append(node.right) #把右节点加入队列
注意:数组下标从0开始,所以代码中每层最后一个元素是N-1
通过广度优先遍历就可以自顶向下找到这些具有下划线的节点,每条线上的数字代表访问他们的顺序,如图:
最终代码:
class TreeNode(object):#定义二叉树的根节点为TreenNode
def __init__(self,x):
self.val = x #定义二叉树的每个元素的值,这里表示柠檬的编号
self.left = None #定义二叉树的每个元素的左子树
self.right = None #定义二叉树的每个元素的右子树
def rightSide(root):
result = []#存放结果数据
queue = [root]#先队列存放待处理数据
while len(queue) > 0:# 队列长度不为空则继续循环
length = len(queue)#获取队列长度
for i in range(length):#以此处理每一行
node = queue.pop() #取出队列头的点
if i == length - 1: #当该点时最后一个点的时候把他加入结果数组里
result.append(node.val)
if node.left != None:
queue.append(node.left)#把左节点加入队列
if node.right != None:
queue.append(node.right)#把右节点加入队列
return result
node1 = TreeNode(1) #以下为测试代码
node2 = TreeNode(2)
node3 = TreeNode(3)
node1.right = node2
node2.right = node3
print(rightSide(node1))