【剑指offer】树题目集合

二叉搜索树的第k个节点

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

# 中序遍历时相减
class Solution:
    # 返回对应节点TreeNode
    def __init__(self):
        self.cnt = 0
    def KthNode(self, pRoot, k):
        # write code here
        if not pRoot: return None
        node = self.KthNode(pRoot.left,k)
        if node:
            return node
        self.cnt+=1
        # print(self.cnt)
        if self.cnt==k:
            return pRoot
        node = self.KthNode(pRoot.right,k)
        if node:
            return node

二叉树的深度

class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        if not pRoot:
            return 0
        else:
            # 左子树高度
            LD = self.TreeDepth(pRoot.left)
            # 右子树高度
            RD = self.TreeDepth(pRoot.right)
            return max(LD, RD)+1

平衡二叉树

class Solution:
    def IsBalanced_Solution(self, pRoot):
        if not pRoot:return True
        if abs(self.maxDepth(pRoot.left)-self.maxDepth(pRoot.right))>1:return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)

    def maxDepth(self,root):
        if not root:return 0
        left = self.maxDepth(root.left)
        right = self.maxDepth(root.right)
        return max(left,right)+1

树中最近公共祖先

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        if not root: return None
        if root==p or root==q: return root
        left = self.lowestCommonAncestor(root.left,p,q)
        right = self.lowestCommonAncestor(root.right,p,q)
        if left and right: return root
        if left: return left
        return right

二叉搜索树的后序遍历序列

class Solution:
    def VerifySquenceOfBST(self, sequence):
        if not sequence:return False
        n = len(sequence)
        root = sequence[-1]
        k = 0
        while k < n and sequence[k] < root:k += 1
        for i in range(k,n):
            if sequence[i]<root:return False
        left = True
        if k > 0:# 说明有左子树
            left = self.VerifySquenceOfBST(sequence[0:k])
        right = True
        if k < n-1: # 若右子树存在
            right = self.VerifySquenceOfBST(sequence[k:-1])
        return left and right

二叉树和为某个值的路径

class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        res = []
        path = []
        if not root:return res
        self.dfs(root,expectNumber,path,res)
        return res


    def dfs(self,root,sum,path,res):
        # print(sum)
        # if not root: return
        path.append(root.val)
        sum -= root.val
        if not root.left and not root.right and sum==0:
            # print(path)
            res.append(path[:])
        if root.left:
            self.dfs(root.left,sum,path,res)
        if root.right:
            self.dfs(root.right,sum,path,res)
        path.pop()

二叉树的下个节点(父亲节点)

# 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
# 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针
class TreeLinkNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        self.next = None
class Solution:
    def GetNext(self, pNode):
        if not pNode: return None
        if pNode.right:
            p = pNode.right
            while p.left:
                p = p.left
            return p
        while pNode.next and pNode==pNode.next.right:
            pNode = pNode.next
        return pNode.next

二叉树的镜像

class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if not root:return root
        self.Mirror(root.left)
        self.Mirror(root.right)
        root.left,root.right = root.right,root.left

对称二叉树

class Solution:
    def isSymmetrical(self, pRoot):
        if not pRoot:return True
        return self.helper(pRoot.left,pRoot.right)
    def helper(self,p,q):
        if not p or not q:return not p and not q
        # 只有两棵树都是空的才是空
        if p.val != q.val:return False
        return self.helper(p.left,q.right) and self.helper(p.right,q.left)

序列化二叉树

class TreeNode:
    """
     1. 对于序列化:使用前序遍历,递归的将二叉树的值转化为字符,并且在每次二叉树的结点
        不为空时,在转化val所得的字符之后添加一个' , '作为分割。对于空节点则以 '#' 代替。
     2. 对于反序列化:按照前序顺序,递归的使用字符串中的字符创建一个二叉树(特别注意:
    在递归时,递归函数的参数一定要是char ** ,这样才能保证每次递归后指向字符串的指针会
    随着递归的进行而移动!!!)
    """
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def Serialize(self, root):
        self.res = ""
        self.helper(root)
        return self.res
    def helper(self,root):
        if not root:
            self.res += "#,"
            return
        #     s = '$,' 等价
        #     return s
        self.res += str(root.val)+','
        self.helper(root.left)
        self.helper(root.right)

    def Deserialize(self, s):
        lista = s.split(',')
        return self.helper_de(lista)

    def helper_de(self,tree):
        if not tree:return None
        val = tree.pop(0)
        root = None
        if val != "#":
            root = TreeNode(int(val))
            root.left = self.helper_de(tree)
            root.right = self.helper_de(tree)
        return root

之字形打印二叉树 

class Solution:
    def Print(self, pRoot):
        rs = []
        flag = 1
        if not pRoot: return rs
        queue = []
        queue.append(pRoot)
        while queue:
            cur_level,size = [],len(queue)
            for i in range(size):
                tmp = queue.pop(0)
                cur_level.append(tmp.val)
                if tmp.left:
                    queue.append(tmp.left)
                if tmp.right:
                    queue.append(tmp.right)
            rs.append(cur_level[::flag])
            flag*=-1

树的子结构

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        if not pRoot1 or not pRoot2:
            return False
        if self.isPart(pRoot1,pRoot2): return True
        return self.HasSubtree(pRoot1.left,pRoot2) \
               or self.HasSubtree(pRoot1.right,pRoot2)
    def isPart(self,p1,p2):
        # 如果p2是空,说明小的子树遍历结束
        if not p2: return True
        if not p1 or (p1.val != p2.val): return False
        return self.isPart(p1.left,p2.left) \
               and self.isPart(p1.right,p2.right)

先序、中序重建二叉树

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        self.pre = pre
        self.tin = tin
        self.hashmap = {}
        for idx,node in enumerate(tin):
            self.hashmap[node]=idx
        # print(hashmap)
        return self.dfs(0,len(pre)-1,0,len(tin)-1)

    def dfs(self,pl,pr,il,ir):
        if pl>pr:return None
        root = TreeNode(self.pre[pl])
        k = self.hashmap[root.val]
        # 寻找左子树,在前序遍历找,在中序遍历找
        left = self.dfs(pl+1,k-il+pl,il,k-1)
        right = self.dfs(k-il+pl+1,pr,k+1,ir)
        root.left = left
        root.right = right
        return root

二叉树先序遍历(非递归)

# 先序打印二叉树(非递归)
def preOrderTravese(node):
    stack = [node]
    while len(stack) > 0:
        print(node.val)
        if node.right is not None:
            stack.append(node.right)
        if node.left is not None:
            stack.append(node.left)
        node = stack.pop()

二叉树中序遍历(非递归)

# 迭代
def inorderTraversal(self, root):
    stack,res = [],[]
    cur = root
    while stack or cur:# 根节点的右子树还未遍历完,此时cur非空
        while cur:
        # travel to each node's left child, till reach the left leaf
            stack.append(cur)
            cur = cur.left
        if stack: # 可以省略
            # this node has no left child
            cur = stack.pop()
            # so let's append the node value 
            res.append(cur.val)
            cur = cur.right
    return res

二叉树后序遍历(非递归)

# 后序打印二叉树(非递归)
# 使用两个栈结构
# 第一个栈进栈顺序:左节点->右节点->根节点
# 第一个栈弹出顺序: 根节点->右节点->左节点(先序遍历栈弹出顺序:根->左->右)
# 第二个栈存储为第一个栈的每个弹出依次进栈
# 最后第二个栈依次出栈
def postOrderTraverse(node):
    stack = [node]
    stack2 = []
    while len(stack) > 0:
        node = stack.pop()
        stack2.append(node)
        if node.left is not None:
            stack.append(node.left)
        if node.right is not None:
            stack.append(node.right)
    while len(stack2) > 0:
        print(stack2.pop().val)

二叉树层次遍历

def levelOrder(self, root):
    """
    :type root: TreeNode
    :rtype: List[List[int]]
    """
    queue = []
    rs = []
    if root:
        queue.append(root)
        while queue:
            cur_level,size = [],len(queue)
            for _ in range(size):
                tmp = queue.pop(0)
                cur_level.append(tmp.val)
                if tmp.left:
                    queue.append(tmp.left)
                if tmp.right:
                    queue.append(tmp.right)
            rs.append(cur_level[:])
    return rs

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值