写作目的
二叉树是程序设计中经常用到的数据结构,一些统计学习算法比如说决策树,以及由此衍生出来的随机森林,GBDT,XGBOOST,ADABOOST等,都多多少少的涉及到了二叉树操作以及树操作,在我们面试的过程中也经常的遇见二叉树的重构等,
二叉树遍历
接下来展示,前序、后续、中序遍历的递归和非递归实现
前序
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def preorderTraversal(self, root):#迭代实现
"""
:type root: TreeNode
:rtype: List[int]
"""
def backTrack(root):
if root:
res.append(root.val)
backTrack(root.left)
backTrack(root.right)
res=[]
backTrack(root)
return res
def preorderTraversal1(self, root):#迭代实现
"""
:type root: TreeNode
:rtype: List[int]
"""
stack=[root]
res=[]
while stack:#前序遍历中左右,所以下一次左在栈顶
bePop=stack.pop()
res.append(bePop.val)
if bePop.right:
stack.append(bePop.right)
if bePop.left:
stack.append(bePop.left)
return res
root=TreeNode(1)
root.left=TreeNode(2)
root.right=TreeNode(3)
root.left.left=TreeNode(4)
root.left.right=TreeNode(5)
root.right.left=TreeNode(6)
root.right.right=TreeNode(7)
s=Solution()
print(s.preorderTraversal(root))
print(s.preorderTraversal1(root))
后续
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def postorderTraversal(self, root):#迭代实现
"""
:type root: TreeNode
:rtype: List[int]
"""
res=[]
def postOrder(root):
if root:
postOrder(root.left)
postOrder(root.right)
res.append(root.val)
res=[]
postOrder(root)
return res
def postorderTraversal1(self, root): # 栈的是实现方式
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack=[root]
while stack:
bePop=stack.pop()#中被拿出来了,下一个留在栈顶的一定需要是右分支(左右中)
res.append(bePop.val)
if bePop.left:
stack.append(bePop.left)
if bePop.right:
stack.append(bePop.right)
return res[::-1]
root=TreeNode(1)
root.left=TreeNode(2)
root.right=TreeNode(3)
root.left.left=TreeNode(4)
root.left.right=TreeNode(5)
root.right.left=TreeNode(6)
root.right.right=TreeNode(7)
s=Solution()
print(s.postorderTraversal(root))
print(s.postorderTraversal1(root))
中序
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def inorderTraversal(self, root):#迭代的实现方式
"""
:type root: TreeNode
:rtype: List[int]
"""
def backTrack(root):
if root:
backTrack(root.left)
res.append(root.val)
backTrack(root.right)
res=[]
backTrack(root)
return res
def inorderTraversal2(self, root):#栈的实现方式
"""
:type root: TreeNode
:rtype: List[int]
"""
stack=[]
res=[]
while root or stack:#左中右所以下个栈顶一定是右
while root:
stack.append(root)
root=root.left
bePop=stack.pop()
res.append(bePop.val)
root=bePop.right
return res
root=TreeNode(1)
root.left=TreeNode(2)
root.right=TreeNode(3)
root.left.left=TreeNode(4)
root.left.right=TreeNode(5)
root.right.left=TreeNode(6)
root.right.right=TreeNode(7)
s=Solution()
print(s.inorderTraversal(root))
print(s.inorderTraversal2(root))
根据遍历序列重构二叉树
其实这个问题,关键在于对序列相对位置的定位。
根据二叉树前序中序列构造二叉树
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
迭代关系出来了,递归代码也就呼之欲出了。
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def __init__(self):
self.preorderList=[]
self.inorderList=[]
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if not preorder: return None
thisNode=TreeNode(preorder[0])
idx=inorder.index(preorder[0])
thisNode.left=self.buildTree(preorder[1:idx+1],inorder[:idx])
thisNode.right=self.buildTree(preorder[idx+1:],inorder[idx+1:])
return thisNode
根据二叉树中序与后续重构二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
if not postorder:return None
thisNode=TreeNode(postorder[-1])
idx=inorder.index(postorder[-1])
thisNode.left=self.buildTree(inorder[:idx],postorder[:idx])
thisNode.right=self.buildTree(inorder[idx+1:],postorder[idx:-1])#保持大小的一致性
return thisNode
清清爽爽,优雅自在的代码,才舒服!。