树是数据结构和算法中非常重要,也是很基础的环节,做题的方法要先想到递归和循环遍历,本文就用Python根据以下知识点对应提醒进行总结。
树的种类:完全二叉树、平衡二叉树、二叉排序树(搜索)、哈夫曼树、B树概念。
树的的遍历:前序遍历、中序遍历、后序遍历、层次遍历;BFS,DFS。
树的最基本结构:
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
-
前序遍历(中序、后续同理)
-
# 递归 根左右顺序 def PreOrderTraverse(self, pNode): if pNode is None: return print(pNode.val) self.PreOrderTraverse(pNode.left) self.PreOrderTraverse(pNode.right)
#非递归方法借助栈 def PreOrderTraverse(self, pNode): stack, res = [], [] while stack or pNode: if pNode: res.append(pNode.val) stack.append(pNode) pNode = pNode.left else: pNode = stack.pop() pNode = pNode.right return res
剑指offer 按行打印二叉树
思路:相当于BFS广度优先遍历,借用一个队列queue来实现,python中可使用list当队列。每个节点遍历
时把左右孩子节点压入队列之中。def LevelTraverse(self, pNode): if pNode is None: return queue = [pNode] while queue: p = queue.pop(0) print(p.val) if p.left: self.LevelTraverse(p.left) if p.right: self.LevelTraverse(p.right)
-
二叉树深度(很多题需要用到)
def TreeDepth(self, pNode): if not pNode: return 0 return max(self.TreeDepth(pNode.left),self.TreeDepth(pNode.right))+1
-
第k层有多少个节点
def GetNodeNumKthlevel(self, pNode, k): if pNode is None or k<1: return 0 if k == 1: return 1 return self.GetNodeNumKthlevel(pNode.left, k-1) + self.GetNodeNumKthlevel(pNode.right,k-1)
-
叶子节点个数
def GetLeafNodeNum(self, pNode): if pNode is None: return 0 if pNode.left is None and pNode.right is None: return 1 return self.GetLeafNodeNum(pNode.right) + self.GetLeafNodeNum(pNode.left)
-
二叉树结构是否相同
#递归到两节点为None为止 def Treecmp(self, p1, p2): if p1 is None and p2 is None: return True if p1 is None or p2 is None: return False return self.Treecmp(p1.left, p2.left) and self.Treecmp(p1.right, p2.right)
-
二叉树镜像
def TreeMirror(self, pNode): if pNode is None: return left = self.TreeMirror(pNode.left) right = self.TreeMirror(pNode.right) pNode.left = left pNode.right =right return pNode
-
平衡二叉树最低公共节点
def FindNode(self, pNode, p): if pNode is None or p is None: return False if pNode == p: return True return self.FindNode(pNode.left, p) or self.FindNode(pNode.right, p) def GetLastComParent(self, pNode, p1, p2): if self.FindNode(pNode.left, p2) and self.FindNode(pNode.right, p1): return pNode else: return self.GetLastComParent(pNode.right, p1, p2) if self.FindNode(pNode.left, p1) and self.FindNode(pNode.right, p2): return pNode else: return self.GetLastComParent(pNode.right, p1, p2)
-
剑指Offer(三十九)平衡二叉树
# 递归 从根节点向下遍历高度的方法
class Solution:
def IsBalanced_Solution(self, pRoot):
if not pRoot:
return True
leftDepth = self.getDepth(pRoot.left)
rightDepth = self.getDepth(pRoot.right)
return abs(leftDepth-rightDepth)<=1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
def getDepth(self, p):
if not p:
return 0
leftDepth = self.getDepth(p.left)
rightDepth = self.getDepth(p.right)
return max(leftDepth,rightDepth)+1
#从叶子开始向上计算的方法,用时更少,减去了很多重复的计算
class Solution:
def IsBalanced_Solution(self, p):
return self.dfs(p)!=-1
def dfs(self, p):
if not p:
return 0
if self.dfs(p.left)==-1:
return -1
if self.dfs(p.right)==-1:
return -1
if abs(self.dfs(p.right) - self.dfs(p.left)) > 1:
return -1
return max(self.dfs(p.right),self.dfs(p.left)) + 1