Leetcode 刷题第13天 |144, 145, 94

导言

对于二叉树,无疑是Leetcode 刷题最难的部分之一,对小编也是如此,从今天开始学习或复习二叉树。
对于二叉树,我们要了解一下几个方面知识:
一、二叉树种类

  • 满二叉树
    如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。如图所示:
    满二叉树
  • 完全二叉树
    一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。(简单理解为,完全二叉树只有最后一层不满,但只有右边没有节点)
    由此可知,满二叉树是特殊的完全二叉树。如图所示:
    完全二叉树
  • 二叉搜索树(又,二叉查找树(Binary Search Tree),二叉排序树)
    是一个有数据的树,也就是节点上有数值,满足三个条件。
  1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 它的左、右子树也分别为二叉排序树
    二叉搜索树
  • 平衡二叉搜索树
    平衡二叉搜索树的任何结点的左子树和右子树高度最多相差1。
    平衡二叉搜索树

二、 二叉树的存储方式

  1. 链式存储
  2. 线性存储

三、 二叉树的遍历方式

  1. 深度优先遍历(前序遍历,中序遍历,后序遍历)【递归法 ,迭代法】
  2. 广度优先遍历(层次遍历 )【迭代法】

Leetcode 144 先序遍历

题目:

给你二叉树的根节点root,返回它的节点值的 前序 遍历。
示例1:
实例1
输入: root = [1,null,2,3]
输出: [1,2,3]
示例2:
输入: root = []
输出: []
示例3:
输入: root = [1]
输出: [1]
示例4:
示例4
输入: root = [1,2]
输出: [1,2]
示例5:
示例5
输入: root = [1,null,2]
输出: [1,2]
提示:

  • 树中节点数量在范围[0, 100]内
  • -100 <= Node.val <= 100

算法思想:

前序遍历的节点是“中,左,右”。递归算法注意三个要点:1、传入什么参数 2、递归结束条件 3、单层递归的逻辑。如代码中TreeNode 所示,树结构为链式结构,因此传入树的root节点即可,其余节点通过指针搜索。递归结束条件当然是指针走到叶子结点后没有可以走的节点。
迭代法利用栈的结构解决问题,将根节点入栈后,栈不空,从栈顶中弹出元素。因为目标遍历顺序是“根,左,右”,因此,为了这个效果,先对右子树进栈,再将左子树进栈。

代码实现:

  1. 递归法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root: TreeNode):
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return  [root.val] + left +  right
  1. 迭代法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root):
        # 根节点是否为None
        if not root:
            return []
        stack = [root]  # 访问节点
        result = []     # 处理节点保存
        while stack:
            # 访问节点
            node = stack.pop()
            # 中节点优先处理
            result.append(node.val)
            # 右孩子先入栈
            if node.right:
                stack.append(node.right)
            # 左孩子后入栈
            if node.left:
                stack.append(node.left)
        return result

Leetcode 145 后序遍历

题目:

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
示例1
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100

算法思想:

后序遍历类似于前序遍历。后序遍历的节点是“左,右,中”。不难发现,前序遍历是“中,左,右”,因此,在跌打实现中,只需要先序遍历先遍历左子树,后遍历右子树,最后翻转即可。

代码实现

  1. 递归法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root: TreeNode):
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return left +  right + [root.val]
  1. 迭代法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def postorderTraversal(self, root):
        '''
            在先序遍历的基础上,入栈顺序调换一下;
            在逆序即可
        '''
        if not root:
            return []
        result = []
        stack = [root]
        while stack:
            node = stack.pop()
            
            # 中节点先处理
            result.append(node.val)

            # 左孩子先入栈
            if node.left:
                stack.append(node.left)
            
            # 右孩子入栈
            if node.right:
                stack.append(node.right)
            
        # 将最终结果翻转
        return result[::-1]

Leetcode 94 中序遍历

题目

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
示例1
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

算法思想:

中序遍历的思想是“左,中,右”。

代码实现:

  1. 递归法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def preorderTraversal(self, root: TreeNode):
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return left + [root.val] + right
  1. 迭代法
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    
class Solution:
    def inorderTraversal(self, root):
        if not root:
            return []
        stack = []
        result = []
        cur = root
        while cur or stack:
            # 一路向左
            if cur:
                stack.append(cur)
                cur = cur.left
            else:
                # 左为空,返回到上一个节点;指向当前节点的右节点,如果右节点在为空的话,在出栈一个元素
                cur = stack.pop()
                result.append(cur.val)
                # 栈顶元素在向右走
                cur = cur.right
        return result
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值