代码随想录Day-14|二叉树理论基础篇|递归遍历|迭代遍历|统一迭代

清单

● 理论基础
● 递归遍历
● 迭代遍历
● 统一迭代

理论基础

二叉树的种类:
满二叉树/ 完全二叉树/ 二叉搜索树/ 平衡二叉搜索树

二叉树的存储方式:
二叉树可以链式存储,也可以顺序存储

如果使用数组存储二叉树
如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2

二叉树的遍历方式

  1. 深度优先遍历: 先往深走,遇到叶子结点再往回走。
  2. 广度优先遍历: 一层一层的去遍历。

1. 二叉树的递归遍历

● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历

2. 思路

  1. 确定递归函数的参数和返回值
  2. 确定终止条件
  3. 确定单层递归的逻辑

3. 代码实现

#144 二叉树的前序遍历
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: Optional[TreeNode]):
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)
        return [root.val] + left + right
        
#145 二叉树的后序遍历
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: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

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

        return left + right + [root.val]

#94 二叉树的中序遍历
class TreeNode:
    def __init__(self, val = 0, left = None, right = None):
        self.val = 0
        self.left = left
        self.right = right

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

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

        return left + [root.val] + right

2. 二叉树的迭代遍历

1. 题目

● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历

2. 思路

递归的实现: 每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,递归返回,从栈顶弹出上一次递归的各项参数。
#前序遍历 - 访问顺序和读取顺序一致,因此使用node记录每一次弹出元素。最终return结果为中左右,因此入栈顺序应该为右左中
#后续遍历 访问顺序同读取顺序不一致,最终return结果为左右中,观察可通过更改前序遍历部分代码实现,即更改入栈顺序为左右中,最后return结果反转即可
#中序遍历 访问顺序同读取顺序不一致,借用指针来记录访问顺序,先遍历到二叉树最底部依次记录左侧元素,

3. 代码实现

#144 二叉树的前序遍历
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: Optional[TreeNode]) -> List[int]:
        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

#145 二叉树的后序遍历
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: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        stack = [root]
        result = []
        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]
 
 #94 二叉树的中序遍历
 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: Optional[TreeNode]) -> List[int]:
        #访问顺序和入栈顺序不一致,使用指针记录访问,所以此时stack为空,便于记录访问顺序
        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

统一迭代

1. 题目

● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历

2. 思路

通过将要处理的节点放入栈之后,紧接着放入一个空指针作为标记,达到统一迭代代码的实现

3. 代码实现

#144 二叉树的前序遍历
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: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            if node != None:
                if node.right:
                    stack.append(node.right)
                if node.left:
                    stack.append(node.left)
                stack.append(node)
                stack.append(None)
            else:
                node = stack.pop()
                result.append(node.val)
        return result

#145 二叉树的后序遍历
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: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            if node != None:
                stack.append(node)
                stack.append(None)
                if node.right:
                    stack.append(node.right)
                if node.left:
                    stack.append(node.left)
            else:
                node = stack.pop()
                res.append(node.val)
        return res

#94 二叉树的中序遍历
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: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            if node != None:
                if node.right:
                    stack.append(node.right)
                
                stack.append(node)
                stack.append(None)
                if node.left:
                    stack.append(node.left)
            else:
                node = stack.pop()
                res.append(node.val)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
叉树的遍有三种方式:前序遍、中序遍和后序遍。其中,归遍是比较常见的方式,而非归遍则需要借助栈的数据结构实现。 下面给出二叉树归遍和非归遍的C语言代码实现: 1. 二叉树归遍 前序遍: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } printf("%d ", root->val); // 访问根节点 preorderTraversal(root->left); // 归遍左子树 preorderTraversal(root->right); // 归遍右子树 } ``` 中序遍: ``` void inorderTraversal(TreeNode* root) { if (root == NULL) { return; } inorderTraversal(root->left); // 归遍左子树 printf("%d ", root->val); // 访问根节点 inorderTraversal(root->right); // 归遍右子树 } ``` 后序遍: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } postorderTraversal(root->left); // 归遍左子树 postorderTraversal(root->right); // 归遍右子树 printf("%d ", root->val); // 访问根节点 } ``` 2. 二叉树的非归遍 前序遍: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } stack<TreeNode*> st; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); st.pop(); printf("%d ", node->val); // 访问节点 if (node->right != NULL) { st.push(node->right); // 右子节点先入栈,保证左子节点先出栈 } if (node->left != NULL) { st.push(node->left); } } } ``` 中序遍: ``` void inorderTraversal(TreeNode* root) { stack<TreeNode*> st; TreeNode* node = root; while (!st.empty() || node != NULL) { if (node != NULL) { // 当前节点不为空,继续将其左子节点入栈 st.push(node); node = node->left; } else { // 当前节点为空,说明已经到达最左侧,开始出栈访问节点 node = st.top(); st.pop(); printf("%d ", node->val); // 访问节点 node = node->right; // 开始访问右子节点 } } } ``` 后序遍: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } stack<TreeNode*> st1, st2; st1.push(root); while (!st1.empty()) { TreeNode* node = st1.top(); st1.pop(); st2.push(node); // 先将当前节点入栈st2 if (node->left != NULL) { st1.push(node->left); // 左子节点入栈st1 } if (node->right != NULL) { st1.push(node->right); // 右子节点入栈st1 } } while (!st2.empty()) { // 出栈访问节点 TreeNode* node = st2.top(); st2.pop(); printf("%d ", node->val); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值