代码随想录算法训练营DAY14|理论基础、递归遍历、迭代遍历、统一迭代

理论基础

二叉树的种类

  • 满二叉树
    • 如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。也可以说深度为k,有2^k-1个节点的二叉树。
  • 完全二叉树
    • 除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。
    • 之前我们刚刚讲过优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。
  • 二叉搜索树
    • 前面介绍的树,都没有数值的,而二叉搜索树是有数值的了,二叉搜索树是一个有序树
      • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
      • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
      • 它的左、右子树也分别为二叉排序树
  • 平衡二叉搜索树
    • 又被称为AVL(Adelson-Velsky and Landis)树,具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树的存储方式

  • 二叉树可以链式存储,也可以顺序存储。
  • 链式存储方式就用指针, 顺序存储的方式就是用数组。
  • 顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在各个地址的节点串联一起。
  • 用数组来存储二叉树如何遍历:如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。

二叉树的遍历方式

  • 深度优先遍历
    • 前序遍历(递归法,迭代法):中左右
    • 中序遍历(递归法,迭代法):左中右
    • 后序遍历(递归法,迭代法):左右中
  • 广度优先遍历
    • 层次遍历(迭代法)

二叉树的定义

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

递归遍历

二叉树遍历题目链接

递归三要素

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def Traversal(self, node, result):
        if node == None: 
            return
            
        result.append(node.val)
        self.Traversal(node.left, result)
        self.Traversal(node.right, result)

    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []
        self.Traversal(root, result)

        return result

后序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def Traversal(self, node, result):
        if node == None: 
            return
            
        self.Traversal(node.left, result)
        self.Traversal(node.right, result)
        result.append(node.val)

    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        result = []
        self.Traversal(root, result)

        return result

中序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def Traversal(self, node, result):
        if node == None: 
            return
            
        self.Traversal(node.left, result)
        result.append(node.val)
        self.Traversal(node.right, result)

    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []
        self.Traversal(root, result)

        return result

迭代遍历

前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root: 
            return []
        
        st = [root]
        result = []
        while st:
            node = st.pop()
            result.append(node.val)
            if node.right:
                st.append(node.right)
            if node.left:
                st.append(node.left)

        return result

后序遍历

  • 入栈顺序:左右,出栈顺序:中右左,反转后:左右中
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        if not root: 
            return []
        
        st = [root]
        result = []

        while st: 
            node = st.pop()
            result.append(node.val)

            if node.left:
                st.append(node.left)
            if node.right:
                st.append(node.right)

        return result[::-1]

中序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        st = []
        result = []
        node = root

        while st or node:
            if node:
                st.append(node)
                node = node.left
            else:
                node = st.pop()
                result.append(node.val)
                node = node.right

        return result

统一迭代

中序遍历

  • 注意入栈出栈顺序是反的
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        st = [root]
        result = []

        while st:
            node = st[-1]
            if node:
                st.pop()
                if node.right:
                    st.append(node.right)
                st.append(node)
                st.append(None)
                if node.left:
                    st.append(node.left)
            else:
                st.pop()
                result.append(st.pop().val)

        return result

前序遍历

  • 因为出栈顺序与入栈顺序相反,所以前序时节点是最后入栈的
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root: 
            return []
        
        st = [root]
        result = []

        while st:
            node = st[-1]
            if node:
                st.pop()
                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
                st.append(node)
                st.append(None)
            else:
                st.pop()
                result.append(st.pop().val)
        
        return result

后序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        if not root: 
            return []
        
        st = [root]
        result = []

        while st: 
            node = st.pop()
            if node:
                st.append(node)
                st.append(None)

                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
                    
            else:
                result.append(st.pop().val)
        
        return result
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值