1.题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
思路:
第一种方式类似先序遍历,先遍历非叶子节点的左节点,然后加入根节点,最后遍历非叶节点的右节点,在遍历的过程中将这些节点加入到数组中,最后返回数组中第k-1个元素,即为第k小节点。
第二种方式,先将左节点加入到栈中,直到左节点为叶子节点,弹出此节点,计数加1;
遍历弹出节点的右节点,若不为空,将右节点加入到栈中,继续遍历右节点的左子节点,直到左子节点为空,弹出此节点,计数加1;
class Solution:
# 返回对应节点TreeNode
def KthNode(self, pRoot, k):
self.res=[]
self.dfs(pRoot)
return self.res[k-1] if 0<k<=len(self.res) else None
def dfs(self,root):
#类似先序遍历
if not root:return
self.dfs(root.left)
self.res.append(root)
self.dfs(root.right)
class Solution:
# 返回对应节点TreeNode
def KthNode(self, pRoot, k):
# write code here
stack=[]
node=pRoot
while node:
stack.append(node)
node=node.left
cnt=1
while(stack and cnt<=k):
node=stack.pop()
right=node.right
while right:
stack.append(right)
right=right.left
cnt+=1
if node and k==cnt-1:
return node
return None
2题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
思路:
序列化是指通过前序遍历把二叉树变成数组
反序列化是指重建二叉树
代码:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
#序列化是指通过前序遍历把二叉树变成数组
#反序列化是指重建二叉树
'''
def Serialize(self, root):
# write code here
def doit(node):
if node:
vals.append(str(node.val))
doit(node.left)
doit(node.right)
else:
vals.append('#') #遍历完一个分支加一个#,遇到叶子节点时,其左右子树都为空,则会加2个#
vals=[]
doit(root)
return ''.join(vals)
def Deserialize(self, s):
# write code here
def doit():
val=next(vals)
if val=='#': #遇到#回溯
return None
node=TreeNode(int(val)) #根节点构建
node.left=doit() #构建左子节点
node.right=doit() #构建右子节点
return node
vals=iter(s.split()) #生成一个迭代器,遍历其中的元素
return doit()
'''
def __init__(self):
self.flag = -1
def Serialize(self, root):
# write code here
if not root:
return '#,'
return str(root.val)+','+self.Serialize(root.left)+self.Serialize(root.right)
def Deserialize(self, s):
# write code here
self.flag += 1
l = s.split(',')
if self.flag >= len(s):
return None
root = None
if l[self.flag] != '#':
root = TreeNode(int(l[self.flag]))
root.left = self.Deserialize(s)
root.right = self.Deserialize(s)
return root
3.题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
思路:
借助数组实现每层节点先进先出,先出的节点在遍历其左右子节点加入tmpstack
代码:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if pRoot==None:
return []
stack=[pRoot] #存放一层层节点
ret=[]
while(stack):
tmpstack=[] #存放下一层节点
tmp=[] #存放一层节点的值
for node in stack:
tmp.append(node.val)
if node.left:
tmpstack.append(node.left)
if node.right:
tmpstack.append(node.right)
ret.append(tmp[:]) #一层层的值加入
stack=tmpstack[:] #遍历完一层就将存放下一层的节点赋给stack,tmpstack继续存放下下层节点
return ret
4.题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:
与上一题目类似,之字形打印与从上到下从左到右的打印方式不同处在于偶数层要进行从右到左打印
代码:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Print(self, pRoot):
# write code here
if pRoot==None:
return []
stack=[pRoot]
step=1
ret=[]
while(stack):
tmpstack=[]
tmp=[]
for node in stack:
tmp.append(node.val)
if node.left:
tmpstack.append(node.left)
if node.right:
tmpstack.append(node.right)
#类似从下到下,从左到右的方式,只是第一层从左到右,第二层从右到左,...其中对第二层,第四层的数组元素做个倒排即可
if step%2==0:
tmp.reverse()
ret.append(tmp)
step+=1
stack=tmpstack[:]
return ret
5.题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:
判断一个二叉树是否对称:
①根节点为空,返回True
②根节点不空,左右子节点为空,返回True
③根节点不空,左右子节点不空,值相等且递归调用左子树对称,右子树对称,则返回True;否则返回False
代码:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Symmetrical(self,Lnode,Rnode):
if Lnode==None and Rnode==None:
return True
if Lnode and Rnode:
return Lnode.val==Rnode.val and self.Symmetrical(Lnode.left,Rnode.right) and self.Symmetrical(Lnode.right,Rnode.left)
else:
return False
def isSymmetrical(self, pRoot):
# write code here
#判断一个二叉树是否对称==这棵二叉树与其镜像是相同的
if pRoot==None:
return True
return self.Symmetrical(pRoot.left,pRoot.right)
6.题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路:
1给定节点存在右子节点,则其下一节点是其右子节点的最左节点
#2给定节点作为左节点,不存在右孩子,则其下一节点是其父节点
#3给定节点作为右节点,不存在右孩子,则其下一节点是其父节点的父节点
代码:
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
# write code here
#1给定节点存在右子节点,则其下一节点是其右子节点的最左节点
#2给定节点作为左节点,不存在右孩子,则其下一节点是其父节点
#3给定节点作为右节点,不存在右孩子,则其下一节点是其父节点的父节点
if pNode==None:
return None
#第一种情况:
if pNode.right:
tmp=pNode.right
while tmp.left:
tmp=tmp.left
return tmp
#第二种直接是父节点
p=pNode.next
#第三种情况
while(p and p.right==pNode):
pNode=p
p=p.next
return p