class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
T=TreeNode(1)
n1=T.left=TreeNode(2)
n2=T.right=TreeNode(3)
n3=n1.left=TreeNode(4)
n4=n1.right=TreeNode(5)
DFS(Depth First Search)为二叉树的深度优先遍历方式,深度优先从根节点开始,往深处搜索至某个叶子节点,依据左孩子,右孩子,根节点的相对遍历顺序,可以分为先序遍历(根-左-右),中需遍历(左-根-右),后续遍历(左-右-根)。
深度优先递归解法的三种顺序,框架一致。递归最重要的一点:递归结束条件,(1)当前节点为空,或者递归程序执行完最后一行。
根-左-右 输出:[1,2,4,8,9,5,3,6,7]
class Solution(object):
def PreOrder_rec(self,root):
res=[]
def DFS_pre(node,res):
if node==None:
return
res.append(node.val) # 先中
DFS_pre(node.left,res) # 递归左子树
DFS_pre(node.right,res) # 递归右子树
DFS_pre(root,res)
return res
左-根-右 输出:[8,4,9,2,5,1,6,3,7]
class Solution(object):
def InOrder_rec(self, root):
res=[]
def DFS_In(node,res):
if node==None:
return
DFS_In(node.left,res)
res.append(node.val)
DFS_In(node.right,res)
DFS_In(root,res)
return res
左-右-根 输出[8,9,4,5,2,6,7,3,1]
class Solution(object):
def BackOrder_rec(self, root):
res=[]
def DFS_Back(node,res):
if node==None:
return
DFS_Back(node.left,res)
DFS_Back(node.right,res)
res.append(node.val)
DFS_Back(root,res)
return res
二叉树深度优先迭代 要借助栈(先进后出)的特点。依据三种不同的顺序将不同的节点压入堆栈。
根-左-右 输出:[1,2,4,8,9,5,3,6,7]。维护一个堆栈stack(python中可以用List 高效实现)
从根结点开始(curr=Root);
如果当前节点非空 访问当前结点的值,将当前节点的右子树节点推入堆栈,更新当前结点:curr=curr.left.;
如果当前节点为空:弹出堆栈保存的最后一个右子树结点。
class Solution(object):
def PreOrder_iter(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res=[]
stack=[]
curr=root
while(curr or stack):
if curr:
res.append(curr.val)
stack.append(curr.right) # 递归到叶子结点时,会出现stack 增加None的情形
curr=curr.left # 将None pop 出来就是多了一次无增res操作
else:
curr=stack.pop()
return res
左-根-右 输出:[8,4,9,2,5,1,6,3,7]
维护一个堆栈stack(python中可以用List 高效实现)。
从根结点开始(curr=Root):
如果当前节点非空:将当前结点推入堆栈,更新当前结点:curr=curr.left;
如果当前节点为空:弹出堆栈保存的最后一个结点,访问该结点的值,更新当前结点:curr=curr.right.
class Solution(object):
def InOrer_iter(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res=[]
stack=[]
curr=root
while(curr or stack):
if curr:
stack.append(curr)
curr=curr.left # 一直搜索左子树到叶子节点,将路径上的结点推入堆栈
else:
curr=stack.pop()
res.append(curr.val)
curr=curr.right # 访问右子树结点
return res
左-右-根 输出[8,9,4,5,2,6,7,3,1]
维护一个堆栈stack(python中可以用List 高效实现)。
从根结点开始(curr=Root):
如果当前节点非空:将当前结点推入堆栈,更新当前结点:curr=curr.left;
如果当前节点为空:弹出堆栈保存的最后一个结点,访问该结点的值,更新当前结点:curr=curr.right.
class Solution(object):
def BackOrder_iter(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res=[]
stack=[]
curr=root
while(curr or stack): # 左右根尅分解为:根右左+逆序(根右左和根左右是一样的实现框架)
if curr:
res.append(curr.val)
stack.append(curr.left)
curr=curr.right
else:
curr=stack.pop()
return res[::-1]
BFS(Breadth First Search)为二叉树的广度优先遍历方式,又叫层次遍历从根节点开始逐层遍历二叉树。1->2->3->4->5->6->7->8->9
借助队列 先进后出 的特点,将节点不断推入队列中。python 中用list可以快速实现队列。
迭代解法 输出[1,2,3,4,5,6,7,8,9]
class Solution(object):
def BFS_iter1(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
levels=[]
queue=[root]
if not root:
return levels
while(queue): #
node=queue.pop(0)
levels.append(node.val)
if node.left: # 装进队列里的元素都是非空的。
queue.append(node.left)
if node.right:
queue.append(node.right)
return levels
leetcode 102 要求输出的结果每一层的元素放在一起,则需要维护一个list,用于放置每层的元素,levels=[[1],[2,3],[4,5,6,7],[8,9]],同时一个level变量用于指示当前节点位于的层数。
迭代解法 :输出[[1],[2,3],[4,5,6,7],[8,9]]
class Solution(object):
def levelOrder_iter2(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
levels=[]
queue=[root]
if not root:
return levels
while(queue): # 处理每一层前,增加一次levels,装该层的节点值
levels.append([])
n_q=len(queue) # 该层节点个数
for i in range(n_q): # i:[0,n_q-1] # 逐个处理该层节点:首先弹出队列首,记录数值,有左右孩子的将孩子压入队列
node=queue.pop(0)
levels[-1].append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return levels
递归解法 输出[[1],[2,3],[4,5,6,7],[8,9]]
实际上是利用DFS实现的BFS,每当DFS遍历到一个新的节点,就把它加入到所在层的list里面去。
class Solution(object):
def levelOrder_rec(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
levels=[]
if not root:
return levels
def BFS_rec(node,level):
if len(levels)==level: # level作为levels 的索引,应该
levels.append([])
levels[level].append(node.val) # 将当前节点放入指定的层
if node.left: # 如果有左右孩子,递归调用BFS_rec
BFS_rec(node.left,level+1)
if node.right:
BFS_rec(node.right,level+1)
BFS_rec(root,0)
return levels
参考博文:
二叉树的前中后遍历,层次遍历,树的递归问题(递归与迭代python):https://www.cnblogs.com/liuyicai/p/10156455.html
二叉树及其遍历方法—python实现:https://www.cnblogs.com/lliuye/p/9143676.html
def Max_depth(node):
if node==None:
return 0
dl=DFS(node.left)
dr=DFS(node.right)
res=max(dl,dr)+1
return res
res=Max_depth(root)
return res
def maxDepth(self, root):
de=0
if root:
stack=[(1,root)]
else:
return 0
while(stack):
cur_de,node=stack.pop()
if node: # 只有当结点存在时+1后的深度才会被采用
de=max(de,cur_de)
stack.append((cur_de+1,node.left))
stack.append((cur_de+1,node.right))
return de
自低向上的交换过程
class Solution(object):
def invertTree(self, root):
if root==None:
return
self.invertTree(root.left)
self.invertTree(root.right)
root.left,root.right=root.right,root.left
return root
自顶向下的交换过程
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
if root:
q=[root]
else:
return root
while(q):
curr=q.pop(0)
curr.left,curr.right=curr.right,curr.left
if curr.left:
q.append(curr.left)
if curr.right:
q.append(curr.right)
return root
leetcode617: 两棵树有公共结点处的值为两数对应节点值想加
class Solution(object):
def mergeTrees(self, t1, t2):
if not t1 and not t2:
return None
root=TreeNode(0)
if t1 and t2:
root.val=t1.val+t2.val
root.left=self.mergeTrees(t1.left,t2.left)
root.right=self.mergeTrees(t1.right,t2.right)
elif t1:
root.val=t1.val
root.left=self.mergeTrees(t1.left,None)
root.right=self.mergeTrees(t1.right,None)
else:
root.val=t2.val
root.left=self.mergeTrees(None,t2.left)
root.right=self.mergeTrees(None,t2.right)
return root
class Solution(object):
def mergeTrees2(self, t1, t2):
if t1==None:
return t2
if t2==None:
return t1
t1.val+=t2.val
t1.left=self.mergeTrees2(t1.left,t2.left)
t1.right=self.mergeTrees2(t1.right,t2.right)
return t1
首先把两棵树的根节点入栈,栈中的每个元素都会存放两个根节点,并且栈顶的元素表示当前需要处理的节点。
以t1作为最后的输出返回,
当前结点的处理( 在stack里面的东西都是非空的):
两者相加的值放入t1.val
子结点的处理:
t1没有做孩子,t2的左孩子给t1.
t1,t2同时有左孩子,将其同时入栈,
右孩子的处理同理。
class Solution(object):
def mergeTrees(self, t1, t2):
if t1==None:
return t2
if t2==None:
return t1
stack=[(t1,t2)]
while(stack):
node1,node2=stack.pop() # 在stack里面的东西都是非零的
node1.val+=node2.val
if node1.left==None:
node1.left=node2.left
elif node1.left and node2.left: # 1.left 和2.left同时非零
stack.append([node1.left,node2.left])
if node1.right==None:
node1.right=node2.right # 放过来之后就有。
elif node1.right and node2.right: # 1.left 和2.left同时非零
stack.append([node1.right,node2.right])
return t1