Python 二叉树相关

二叉树

本博文仅用作个人学习的记录,包含个人学习过程的一些思考,想到啥写啥,因此有些东西阐述的很罗嗦,逻辑可能也不清晰,看不懂的且当作是作者的呓语,自行跳过即可。

二叉树是一种数据结构,和链表一样:

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

遍历包括前序、中序、后序遍历三种。
前序:根->左->右 (根->左->左->左(一直到最左)…->右)
中序:左->根->右(最左->上级根->右)
后序:左->右->根(最左->右的最左(如果右存在子树)->右的最左(直到右不存在子树)…->上级根)

必须已知中序遍历和一个其他遍历,才能求出剩下的遍历。

重建二叉树

代表题型:剑指offer 第4题

  • 题目描述
    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

  • 代码

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        if not pre or not tin:
            return None
        # 由前序确定根节点,定位根结点在中序遍历的坐标
        root = TreeNode(pre.pop(0))
        index = tin.index(root.val)
        # 中序遍历根结点左边是左树,右边是右树
        root.left = self.reConstructBinaryTree(pre, tin[:index])
        root.right = self.reConstructBinaryTree(pre, tin[index + 1:])
        return root
  • 解析
    这是由前序和中序重构二叉树的题型,并且树中没有重复值。通过递归实现,函数只需要实现一次分类即可:
  1. 由前序遍历确定根结点
  2. 在中序遍历中找到根节点
  3. 中序遍历中根结点左边为左子树,右边为右子树
  • 问题
    如果树中存在相同值怎么办?

树的子结构

代表题型:剑指offer 第17题

  • 题目描述
    输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

  • 代码

class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        if pRoot1 and pRoot2:
            if self.IsSubtree(pRoot1,pRoot2):
                return True
            return self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2)
        else:
            return False

    def IsSubtree(self, pRoot1, pRoot2):
        if pRoot1 and pRoot2:
            if pRoot1.val == pRoot2.val:
                return self.IsSubtree(pRoot1.left,pRoot2.left) and self.IsSubtree(pRoot1.right,pRoot2.right)
            else:
                return False
        return True if pRoot2 == None else False
  • 解析
    这个问题主要拆分成两个部分,一个是将B的根结点和A的所有结点进行判断,看是否有相等的值;若相等,则判断是否所有子结点都相等。

  • 小结
    不知道是否有更巧妙简洁的解法,之后二刷三刷的时候再更新。
    有空再学习一下Python的代码简写,短而快!emmm 程序员的追求是又短又快???!!!

镜像二叉树

代表题型:剑指offer 第18题

  • 题目描述
    操作给定的二叉树,将其变换为源二叉树的镜像。
二叉树的镜像定义:
         源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5
  • 代码
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        if root and (root.left or root.right):
            root.left, root.right = root.right, root.left
            if root.left:
                self.Mirror(root.left)
            if root.right:
                self.Mirror(root.right)
        return root
  • 解析
    首先判断树是否非空,是否存在左或右子树;
    交换左右子树;
    若存在左(右)子树,递归左(右)子树;
    返回根节点。

  • 小结
    这题还是比较简单的,需要注意的是题目多数时候的输入都不一定是有值的,多数都是包含边界情况,因此在写主函数前需要先确定边界问题,不然容易不知道错哪了。

从上至下打印二叉树

代表题型:剑指offer 第22题

  • 题目描述
    从上往下打印出二叉树的每个节点,同层节点从左至右打印。

  • 代码

class Solution:
    def PrintFromTopToBottom(self, root):
        tree = []
        treeroot = [root]
        for item in treeroot:
            if item:
                tree.append(item.val)
                if item.left:
                    treeroot.append(item.left)
                if item.right:
                    treeroot.append(item.right)
        return tree
  • 解析
    首先分析第一层,对于当前的根结点root,可以直接输出它的值root.val
    	   root
    	   /  \
        left   right

对于第二层,left和right就相当于两个新的root,和原先的root之间除了数量没有别的区别,因此在循环中,我们需要有一个能够灵活存放树的根节点的结构,也就是一个存放root的list。

由于list的可变性,因此判断当前根节点是否存在左(右)子树,若存在就添加在原列表末尾。

由于没有删除treeroot中的值,最后treeroot中存放的应该是由上而下,从左到右,树的所有结点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值