本篇文章根据labuladong的算法小抄汇总二叉树与二叉搜索树的常见算法,采用python3实现
class TreeNode:
def __init__(self,val=0,left=None,right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def invertTree(self,root):
if root is None:
return None
tmp = root.left
root.left = root.right
root.right = tmp
self.invertTree(root.left)
self.invertTree(root.right)
return root
def connect(root):
if root is None:
return None
connectTwoNode(root.left,root.right)
return root
def connectTwoNode(node1,node2):
if (node1 is None) or (node2 is None):
return
node1.next = node2
connectTwoNode(node1.left,node1.right)
connectTwoNode(node2.left,node2.right)
connectTwoNode(node1.right,node2.left)
def flatten(root):
if root is None:
return None
flatten(root.left)
flatten(root.right)
left = root.left
right = root.right
root.left = None
root.right = left
p = root
while p.right is not None:
p = p.right
p.right = right
#超过递归深度
def constructMaximumBinaryTree(nums):
return build(nums, 0, nums.length - 1)
def build(nums, lo , hi):
if lo > hi:
return None
index = -1
maxVal = float("-inf")
for i in range(lo,hi+1):
if maxVal < nums[i]:
maxVal = nums[i]
index = i
root = TreeNode(maxVal)
root.left = build(nums,lo,index-1)
root.right = build(nums,index+1,hi)
return root
def buildTree(preorder,inorder):
return build(preorder,0,len(preorder)-1,inorder,0,len(inorder)-1)
def build(preorder,preStart,preEnd,inorder,inStart,inEnd):
if preStart > preEnd:
return None
rootVal = preorder[preStart]
index = 0
for i in range(inStart,inEnd+1):
if inorder[i] == rootVal:
index = i
break
root = TreeNode(rootVal)
leftSize = index - inStart
root.left = build(preorder,preStart+1,preStart+leftSize,inorder,inStart,index-1)
root.right = build(preorder,preStart+leftSize+1,preEnd,inorder,index+1,inEnd)
return root
class TreeNode:
def __init__(self,val=0,left=None,right=None):
self.val = val
self.left = left
self.right = right
def buildTree(inorder,postorder):
def build(inorder,instart,inend,postorder,poststart,postend):
if instart > inend:
return None
rootValue = postorder[postend]
for i in range(instart,inend+1):
if inorder[i] == rootValue:
index = i
break
root = TreeNode(rootValue)
leftSize = index-instart
root.left = build(inorder,instart,index-1,postorder,poststart,poststart+leftSize-1)
root.right = build(inorder,index+1,inend,postorder,poststart+leftSize,postend-1)
return root
return build(inorder,0,len(inorder)-1,postorder,0,len(postorder)-1)
class treeNode():
def __init__(self,val=0,left=None,right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> ist[Optional[TreeNode]]:
def traverse(root):
if root is None:
return None
left = traverse(root.left)
right = traverse(root.right)
subTree = str(left) + "," + str(right)+ "," + str(root.val)
fre = subTree_fre.setdefault(subTree,0)
if fre == 1:
res.append(root)
subTree_fre[subTree] = fre + 1
return subTree
res = []
subTree_fre = dict()
traverse(root)
return res
class Codec:
def serialize(self,root):
if root is None:
return "None"
return str(root.val)+","+str(self.serialize(root.left))+","+str(self.serialize(root.right))
def deserialize(self,data):
def dfs(datalist):
data = datalist.pop(0)
if data == "None":
return None
root = TreeNode(int(data))
root.left = dfs(datalist)
root.right = dfs(datalist)
return root
datalist = data.split(",")
return dfs(datalist)
class Codec:
def serialize(self,root):
if root is None:
return ""
queue = collections.deque([root])
res = []
while queue:
node = queue.popleft()
if node is None:
res.append("None")
continue
res.append(str(node.val))
queue.append(node.left)
queue.append(node.right)
return ",".join(res)
def deserialize(self,data):
if not data:
return []
dataList = data.split(",")
root = TreeNode(int(dataList[0]))
queue = collections.deque(root)
i = 1
while queue:
node = queue.popleft()
if dataList[i] != "None":
node.left = TreeNode(int(dataList[i]))
queue.append(node.left)
i += 1
if dataList[i] != "None":
node.right = TreeNode(int(data))
queue.append(node.right)
i += 1
return root
class NestedIterator:
def __init__(self,nestedList):
self.q = collections.deque()
self.dfs(nestedList)
def dfs(self,nestedList):
for elem in nestedList:
if elem.isInteger():
self.q.append(elem.getInteger())
else:
self.dfs(elem.getList())
def next(self):
return self.q.popleft()
def hasNext(self):
return len(self.q)
def lowestCommonAncestor(root,p,q):
if root is None:
return None
if (root == p) or (root == q):
return root
left = lowestCommonAncestor(root.left,p,q)
right = lowestCommonAncestor(root.right,p,q)
if (left is not None) and (right is not None):
return root
if (left is None) and (right is None):
return None
return right if left is None else left
完全二叉树:
满二叉树:
#普通二叉树,时间复杂度O(N)
def countNodes(root):
if root is None:
return 0
return 1 + countNodes(root.left) + countNodes(root.right)
#满二叉树,节点总数和树的高度呈指数关系
def countNodes(root):
h = 0
while root:
root = root.left
h += 1
return pow(2,h) - 1
#完全二叉树,时间复杂度O(logN*logN)
def countNodes(root):
if root is None:
return 0
l = root
r = root
hl = 0
hr = 0
while l:
l = l.left
hl += 1
while r:
r = r.right
hr += 1
if hl == hr:
return pow(2,hl) - 1
return 1 + countNodes(root.left) + countNodes(root.right)
stk = collections.deque()
#左侧遍历到底,存入栈
def pushLeftBranch(p):
while p:
#前序遍历代码位置
stk.append(p)
p = p.left
def traverse(root):
visited = TreeNode(-1) #指向上一次遍历完的子树根节点
pushLeftBranch(root)
while stk:
p = stk[-1]
if ((p.left is None) or (p.left == visited)) and (p.right != visited):
#中序遍历代码位置
pushLeftBranch(p.right)
if (p.right is None) or (p.right == visited):
#后序遍历代码位置
visited = stk.pop(-1)
BST特点:
1、对于BST的每个节点node,左子树节点的值 < node的值 < 右子树节点的值
2、对于BST的每个节点node,左子树和右子树都是BST
3、BST的中序遍历结果是有序的(升序)
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.res = 0
self.rank = 0
self.traverse(root,k)
return self.res
def traverse(self,root,k):
if root is None:
return None
self.traverse(root.left,k)
self.rank += 1
if self.rank == k:
self.res = root.val
return
self.traverse(root.right,k)
class Solution():
def convertTree(root):
def convert(root):
if root is None:
return None
convert(root.right)
self.sum += root.val
root.val = self.sum
convert(root.left)
self.sum = 0
convert(root)
return root
def isValidBST(root):
return isValidBST(root,None,None)
def isValidBST(root,min,max):
if root is None:
return True
if min is not None and root.val <= min.val:
return False
if max is not None and root.val >= max.val:
return False
return isValidBST(root.left,min,root) and isValidBST(root.right,root,max)
def search(root,val):
if root is None:
return None
if val > root.val:
return search(root.right,val)
if val < root.val:
return search(root.left,val)
return root
def insertIntoBST(root,val):
if root is None:
return TreeNode(val)
if val > root.val:
root.right = insertIntoBST(root.right,val)
if val < root.val:
root.left = insertIntoBST(root.left,val)
return root
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
def getMin(root):
while root.left is not None:
root = root.left
return root
if root is None:
return None
if root.val == key:
if root.left is None:
return root.right
elif root.right is None:
return root.left
minNode = getMin(root.right)
minNode.left = root.left
minNode.right = root.right
root = minNode
elif root.val < key:
self.deleteNode(root.right,key)
else:
self.deleteNode(root.left,key)
return root
class Solution:
def numTrees(self, n: int) -> int:
memo = [[0 for i in range(n+1)] for j in range(n+1)]
return count(1,n,memo)
def count(lo,hi,memo):
if lo > hi:
return 1
if memo[lo][hi] != 0:
return memo[lo][hi]
res = 0
for i in range(lo,hi+1):
left = count(lo,i-1,memo)
right = count(i+1,hi,memo)
res += left * right
memo[lo][hi] = res
return res
def generateTrees(n):
if n == 0:
return TreeNode()
return build(1,n)
def build(lo,hi):
res = []
if lo > hi:
return r[None]
for i in range(lo,hi+1):
leftTree = build(lo,i-1)
rightTree = build(i+1,hi)
for left in leftTree:
for right in rightTree:
root = TreeNode(i)
root.left = left
root.right = right
res.append(root)
return res
import sys
sum = 0
def maxSumBST(root):
traverse(root)
return maxSum
def traverse(root): #返回[isBST,min,max,sum]
if root is None:
return [1,sys.maxsize,-sys.maxsize-1,0]
left = traverse(root.left)
right = traverse(root.right)
res = [0 for i in range(4)]
if (left[0] == 1) and (right[0] == 1) and (left[2] < root.val < right[1]):
#以root为根的二叉树是BST
res[0] = 1
res[1] = min(left[1],root.val)
res[2] = max(right[2],root.val)
res[3] = left[3] + right[3] + root.val
maxSum = max(maxSum,res[3])
else:
res[0] = 0
return res