二叉树

本文介绍了二叉树的基本概念,包括结点、度、树的深度等,并详细阐述了二叉树的四种遍历方法:先序、中序、后序和层次遍历。同时,结合LeetCode题目,探讨了验证二叉搜索树和二叉树层次遍历的解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树

二叉树

在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

  • 相关术语:
    树的结点(node):包含一个数据元素及若干指向子树的分支;
    孩子结点(child node):结点的子树的根称为该结点的孩子;
    双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
    兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
    祖先结点: 从根到该结点的所经分支上的所有结点
    子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
    结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
    树的深度:树中最大的结点层
    结点的度:结点子树的个数
    树的度: 树中最大的结点度。
    叶子结点:也叫终端结点,是度为 0 的结点;
    分枝结点:度不为0的结点;
    有序树:子树有序的树,如:家族树;
    无序树:不考虑子树的顺序;

遍历二叉树:L、D、R分别表示遍历左子树、访问根结点和遍历右子树,则先(根)序遍历二叉树的顺序是DLR,中(根)序遍历二叉树的顺序是LDR,后(根)序遍历二叉树的顺序是LRD。还有按层遍历二叉树。这些方法的时间复杂度都是O(n),n为结点个数。

leetcode

  1. 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:
    2
   / \
  1   3
输出: true

示例 2:

输入:
    5
   / \
  1   4
     / \
    3   6
输出: false

解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 。

思想:注意到,每层的最大最小约束都是不一样的,所以采用dfs的思想,不断更新最大最小值。在python中,数字可以取很大,要设大一点。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution(object):
    
    def validBST(self,root,small,large):
        if root==None:
            return True
        if small>=root.val or large<=root.val:
            return False  
        return self.validBST(root.left,small,root.val) and self.validBST(root.right,root.val,large)
        
        
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self.validBST(root,-2**32,2**32-1)



102.二叉树的层次遍历

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
思路:层次遍历。定义两个列表,存储当前层的结点和下一层的结点。
两题思路类似
在这里插入图片描述

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        #bfs广度优先搜索,不熟悉可以网上参考bfs代码
        if not root:
            return []#为空则返回空列表
        queue=[root]#使用列表实现队列的功能,首先存储root
        res=[]
        while queue:#当queue不为空时
            nodes=[]#存节点,每次循环前置空,每次只装一部分
            node_values=[]#存节点的值
            for node in queue:
                if node.left:
                    nodes.append(node.left)#将左子树装入队列中
                if node.right:
                    nodes.append(node.right)
                node_values+=[node.val]#因为每次循环node_values都会置空,所以最终结果保存在res里,node_values只是一小部分结果
            res+=[node_values]
            queue=nodes#将新添加的节点重新赋值给queue
        return res

107.二叉树的层次遍历 II

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution(object):
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        #bfs广度优先搜索,不熟悉可以网上参考bfs代码
        if not root:
            return []#为空则返回空列表
        queue=[root]#使用列表实现队列的功能,首先存储root
        res=[]
        while queue:#当queue不为空时
            nodes=[]#存节点,每次循环前置空,每次只装一部分
            node_values=[]#存节点的值
            for node in queue:
                if node.left:
                    nodes.append(node.left)#将左子树装入队列中
                if node.right:
                    nodes.append(node.right)
                node_values+=[node.val]#因为每次循环node_values都会置空,所以最终结果保存在res里,node_values只是一小部分结果
            res=[node_values]+res#实现从底到顶,node_values放前面.
            queue=nodes#将新添加的节点重新赋值给queue
        return res


参考文献
https://blog.csdn.net/dailu11/article/details/80612801
https://blog.csdn.net/hansionz/article/details/81947834

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值