【LeetCode】二叉树的深度优先遍历

前言 

本文展示LeetCode中与二叉树深度优先遍历相关的三道题,读者可以用来借此默写以检验是否熟悉相关算法,其难度为简单,但是我们推荐读者使用进阶版等更难的实现方法。

LeetCode题目

相关题目类型

相关链接

144

二叉树的先序遍历

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

94

二叉树的中序遍历

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

145

二叉树的后序遍历

https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

一、相关API

在实现算法前,如果你对C++/Python的基础API不太熟悉,最好参考下本节内容。

1、C++的API

C++中借助STL实现动态数组、栈、队列时需要调用如下头文件:

#include<cstdlib> /#include<stdlib.h>
#include<queue>
#include <stack>
#include <queue>

C++中借助STL实现动态数组、栈、队列功能的函数对比:

类别

数组功能

功能

队列功能

创建对象

vector<Type> M

stack<Type> M

queue<Type> M

查看当前是否为空

M.empty()

查看现有元素个数

M.size()

向容器中添加元素

M.push_back()

M.push()

M.push()

获取容器取出元素

(获取)M.top()

(删除)M.pop()

(获取)M.front()

(删除)M.pop()

容器元素反向

reverse(result.begin(), result.end());

以上需要注意的是出栈和出队操作是分两步,需要先获取后删除,Python中可以直接获取该元素并且删除。

2、Python的API

Python中借助Python List类型实现动态数组、栈、队列功能的函数对比:

类别

数组功能

功能

队列功能

创建对象

M = []

M = []

M = []

查看当前是否为空

M(可直接使用if判断是否存在)

查看现有元素个数

len(M)

向容器中添加元素

M.append()

M.append()

M.append()

获取容器取出元素

(默认取出最后一个)M.pop()

(需要指定取出第一个)M.pop(0)

容器元素反向

result[::-1]

二、算法流程

如果读者对算法流程不是十分清楚,可以参考如下伪代码:

算法类型

伪代码流程

递归实现(先序为例)

注意:result要设置为全局类型

result   递归函数(node):

       若node为空,返回result;(终止条件)

       将node的值加入result;(处理节点值)

       递归函数(node.left);

       递归函数(node.right)。

       返回result。

先序遍历

input:node 

output:result

初始化结果列表result;

初始化栈stack;

将输入节点node入栈;

当栈stack不为空时:

       取出一个栈顶元素命名为cur,将其加入result;(处理节点值)

       如果 cur的右子树非空,将右子树入栈;

       如果 cur的左子树非空,将左子树入栈。

返回result

中序遍历

input:node

output:result

初始化结果列表result;

初始化栈stack;

将输入节点node设置为指示节点变量cur;

当cur存在或者栈stack不为空时:

       如果cur存在:

              将cur入栈stack;

              更新cur为cur的左节点;

       如果cur不存在:

              取出一个栈顶元素命名为cur,将其加入result;(处理节点值)

              更新cur为cur的右节点。

后序遍历

input:node

output:result

初始化结果列表result;

初始化栈stack,

将输入节点node入栈;

当栈stack不为空时:

       取出一个栈顶元素命名为cur,将其加入result;(处理节点值)

       如果 cur的右子树非空,将右子树入栈;

       如果 cur的左子树非空,将左子树入栈;

反向result;

返回result。

层次遍历

input:node

output:result

初始化结果列表result;

初始化队列queue;

将输入节点node入队;

当队列queue不为空时:

        取出一个队列元素命名为cur,将其加入result;(处理节点值)

       如果 cur的左子树非空,将左子树加入队列;

       如果 cur的右子树非空,将右子树加入队列。

返回result

如果读者对算法流程难以理解,可以记忆如下顺口溜:

先序遍历先入栈,栈不为空就遍历;

出栈一定要处理,先右后左慢入栈;

中序遍历不先入,指示与栈全不空;

存在入栈换左边,不存取栈换右边;

后序遍历同先序,先左后右记反向;

层次遍历同先序,借用队列先左右。

三、相关代码

我们的代码将直接放到同一份代码中,相信读者可非常容易地拆分出各个题目的答案。

1、递归算法(简单版)

Python3版本

# 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:
    result = []
    def preorderTraversal(self, root: TreeNode) :
        if root==None:
            return
        self.result.append(root.val)
        self.preorderTraversal(root.left)
        self.preorderTraversal(root.right)
        
    def inorderTraversal(self, root: TreeNode) :
        if root==None:
            return 
        self.inorderTraversal(root.left)
        self.result.append(root.val)
        self.inorderTraversal(root.right)
        
    def postorderTraversal(self, root: TreeNode):
        if root==None:
            return 
        self.postorderTraversal(root.left)
        self.postorderTraversal(root.right)
        self.result.append(root.val)

C++版本

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    vector<int> result;
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if(root==NULL){
            return result;
        }
        result.push_back(root->val);
        preorderTraversal(root->left);
        preorderTraversal(root->right);
        return result;
    }
public:
    vector<int> inorderTraversal(TreeNode* root) {
        if(root==NULL){
            return result;
        }
        inorderTraversal(root->left);
        result.push_back(root->val);
        inorderTraversal(root->right);
        return result;
    }
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if(root==NULL){
            return result;
        }
        postorderTraversal(root->left);
        postorderTraversal(root->right);
        result.push_back(root->val);
        return result;
    }
};

2、递归算法(进阶版)

Python3版本

# 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) -> List[int]:
        result = []
        if root==None:
            return result
        stack = [root]
        while len(stack)>0:
            cur = stack.pop()
            result.append(cur.val)
            if cur.right:
                stack.append(cur.right)
            if cur.left:
                stack.append(cur.left)
        return result
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        if root==None:
            return result;
        stack = []
        cur = root
        while cur or len(stack)>0:
            if cur:
                stack.append(cur)
                cur = cur.right
            else:
                cur = stack.pop()
                result.append(cur.val)
                cur = cur.left
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        if root==None:
            return result
        stack = [root]
        while len(stack)>0:
            cur = stack.pop()
            result.append(cur.val)
            if cur.left:
                stack.append(cur.left)
            if cur.right:
                stack.append(cur.right)
        result = result[::-1]
        return result

C++版本

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        if(root==NULL){
            return result;
        }
        stack<TreeNode*> stack;
        stack.push(root);
        while(!stack.empty()){
            TreeNode* cur = stack.top();
            stack.pop();
            result.push_back(cur->val);
            if(cur->right){
                stack.push(cur->right);
            }
            if(cur->left){
                stack.push(cur->left);
            }
        }
        return result;
    }
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        if(root==NULL){
            return result;
        }
        stack<TreeNode*> stack;
        TreeNode* cur = root;
        while(cur!=NULL||!stack.empty()){
            if(cur!=NULL){
                stack.push(cur);
                cur = cur->left;
            }
            else{
                cur = stack.top();
                stack.pop();
                result.push_back(cur->val);
                cur = cur->right;
            }
        }
        return result;
    }
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        if(root==NULL){
            return result;
        }
        stack<TreeNode*> stack;
        stack.push(root);
        while(!stack.empty()){
            TreeNode* cur = stack.top();
            stack.pop();
            result.push_back(cur->val);
            if(cur->left){
                stack.push(cur->left);
            }
            if(cur->right){
                stack.push(cur->right);
            }
        }
        reverse(result.begin(), result.end());
        return result;
    }
};

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔法攻城狮MRL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值