教练,我想学二叉树遍历!

2023-05-16

二叉树具有前序、中序、后序三种遍历方式。递归的相信大家都会写,但是迭代的该怎么写呢?怎样的迭代写法才能具有统一性便于理解呢?请看下面具体的做法,每种遍历方式各有2种策略,基于栈的和基于游标指针,使用栈来辅助的。

1.前序遍历

不采用游标指针的做法

void preOrder(TreeNode* root,vector<int>& res){        
    if(root == nullptr) return;                        
    stack<TreeNode*> st;                               
    st.push(root);                                     
    while(!st.empty()){                                
        TreeNode* cur = st.top();st.pop();             
        res.push_back(cur->val);                       
        if(cur->right) st.push(cur->right);            
        if(cur->left) st.push(cur->left);              
    }                                                  
    return;                                            
}                                                                        

采用游标指针的做法

void preOrder(TreeNode* root,vector<int>& res){         
    if(root == nullptr) return;                        
    stack<TreeNode*> st;                               
    TreeNode* cur = root;                              
    while(!st.empty() || cur != nullptr){              
        if(cur){                  
            res.push_back(cur->val);                      
            st.push(cur);                              
            cur = cur->left;                           
        }else{                                         
            cur = st.top();st.pop();                                
            cur = cur->right;                          
        }                                              
    }                                                  
    return;                                            
}                                                      

2.中序遍历

不采用游标指针的做法,这里只能贴个错误的,因为目前看没有这样的解法

void inOrder2(TreeNode* root,vector<int>& res){                                               
    if(root == nullptr) return;                                                               
    stack<TreeNode*> st;                                                                      
    st.push(root);                                                                            
    TreeNode* pre = root;                                                                     
    while (!st.empty()) {                                                                     
        TreeNode* p = st.top();                                                               
        if(p->left && pre != p->left){//这里很难判断左子树是否被访问过,除非你每个节点搞个变量                           
            st.push(p->left);                                                                 
        }else{                                                                                
            st.pop();                                                                         
            res.push_back(p->val);                                                            
            pre = p;                                                                          
            if(p->right) {                                                                    
                st.push(p->right);                                                            
            }                                                                                 
        }                                                                                     
    }                                                                                         
    return ;                                                                                  
}                                                                                             

采用游标指针的做法

 void inOrder(TreeNode* root,vector<int>& res){    
     if(root == nullptr) return;                   
     stack<TreeNode*> st;                          
     TreeNode* cur = root;                         
     while(!st.empty() || cur != nullptr){         
         if(cur){                                  
             st.push(cur);                         
             cur = cur->left;                      
         }else{                                    
             cur = st.top();st.pop();              
             res.push_back(cur->val);              
             cur = cur->right;                     
         }                                         
     }                                             
     return;                                       
 }                                                 

3.后序遍历

不采用游标指针的做法

 void postOrder(TreeNode* root,vector<int>& res){             
     if(root == nullptr) return;                               
     stack<TreeNode*> st;                                      
     TreeNode* pre = root;//                                   
     st.push(root);                                            
     while(!st.empty()){                                       
         TreeNode* cur = st.top();
        // pre = cur->left说明cur没有右子树 ,也可以处理cur了                                  
         if((cur->left == nullptr && cur->right == nullptr)    
                 ||pre == cur->left||pre == cur->right){ 
             res.push_back(cur->val);                          
             st.pop();                                         
             pre = cur;                                        
         }else{                                                
             if(cur->right)  st.push(cur->right);              
             if(cur->left)   st.push(cur->left);               
         }                                                     
     }                                                         
     return;                                                   
 }                                                             

采用游标指针的做法

 vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root == nullptr) return res;
        TreeNode* cur = root;
        TreeNode* pre = root;
        stack<TreeNode*> st;
        while(st.empty() == false || cur != nullptr){
            if(cur != nullptr){
                st.push(cur);
                cur = cur->left;
            }else{
                cur = st.top();
                if(cur->right == nullptr || cur->right == pre){
                    res.push_back(cur->val);
                    st.pop();
                    pre = cur;
                    cur = nullptr;
                }else{
                    cur = cur->right;
                }
            }
        }
        return res;
    }                                                         

总结一下这2种策略的差别以及关键——基于栈的策略,就想办法在每一次迭代处理好栈;基于游标指针的策略,就在每一步处理好游标指针,只在需要的时候去处理辅助栈。听起来像是废话,但是带着这2句话反过头来看代码,会有感悟的。

衣带渐宽终不悔,为伊消得人憔悴。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

教练,我想学二叉树遍历! 的相关文章

  • 毕业设计使用第三方api

    最近要着手毕业设计了 xff0c 本人的毕设是基于android的 xff0c 和公交有关 xff0c 所以想引用第三方的API xff0c 你们觉得可以吗 xff1f
  • meta—learning调研及MAML概述

    背景 Meta Learning xff0c 又称为 learning to learn xff0c Meta Learning希望使得模型获取一种 学会学习 的能力 xff0c 使其可以在获取已有 知识 的基础上快速学习新的任务 xff0
  • ubuntu18.04安装pycharm

    安装方法 xff1a 方法1 xff1a 在ubuntu的应用商店下载 方法2 xff1a 使用tar包解压缩后下载 xff0c 可参考网页 xff1a https blog csdn net mao hui fei article det
  • Python的命令行参数解析

    文章作者 xff1a Tyan 博客 xff1a noahsnail com CSDN 简书 命令行参数解析在编程语言中基本都会碰到 xff0c Python中内置了一个用于命令项选项与参数解析的模块argparse 下面主要介绍两种解析P
  • Matlab 2016a/b中调用GPU速度巨慢的解决办法

    利用caffe的MATLAB接口跑深度学习时 xff0c 设置gpu模式 xff1a caffe set mode gpu xff0c 可以加速运算 xff0c 然而在MATLAB 2016a b中调用gpu时会出现了一个BUG xff0c
  • keras 2.3.0 做上采样 UpSampling2D的时候的维度出错问题解决办法

    简单的说 xff0c 你是不是遇到了这样的问题 xff0c 上一层的数据是 None xff0c 200 14 14 你希望上采样到28x28 H 61 UpSampling2D size 61 2 2 H 你以为能得到 None xff0
  • juju based openstack upgrade (by quqi99)

    作者 张华 发表于 2022 02 17 版权声明 可以任意转载 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http blog csdn net quqi99 问题 客户想将juju管理的openstack从xenia
  • Try Fyde OS on VMWare and Surface (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 02 28 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http blog csdn net quqi99 Insta
  • Installing third-party firmware on x3-55 letv (by quqi99)

    问题 趁贾老板明天回国之前 xff0c 得连夜将他的乐视x3 55电视刷成第三方精简版的固件 xff0e 官方固件安装的内置服务太多不仅占硬盘空间而且都开着也占用内存影响运行速度 xff0e 要安装的是 xff02 蓝同学 xff02 的固
  • Set up debian based maas ha env on xenial by hand (by quqi99)

    准备三个节点 本文将在xenial ubuntu 16 04 使用debian包手工创建maas ha环境 先快速准备三个节点 juju deploy ubuntu maas1 series xenial config hostname m
  • add a wifi AP for armbian box (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 03 26 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http blog csdn net quqi99 无线网卡的
  • Kids are forbidden to watch TV after school (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 03 30 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http blog csdn net quqi99 iptab
  • ubuntu 20.04升级到22.04中遇到的问题(by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 04 23 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http blog csdn net quqi99 昨天通过
  • keil下载代码时出现:“Not a genuine ST Device! Abort connection“的错误

    最近在学习嵌入式 xff0c 难免要玩一些开发板 我选择了相对比较便宜的STM32F10C8T6 所以我就从网上购买了这快板子 刚开始买回来的时候 xff0c 我根本不知道往板子上烧录代码的时候还需要ST LINK 因为我在学F407的时候
  • Testing ovn manually based on LXD (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 05 27 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 准备两个LXD容器 lxc list 43 43 43 43
  • [WIP] Openstack Masakari (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 06 07 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 什么是masakari masakari是OpenStack
  • 远程解决win10上keyboard和chrome不work的两例问题(by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 06 10 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 远程解决了两例windows问题 xff0c 记录一下 xff
  • try anbox or waydroid (by quqi99)

    作者 张华 发表于 2022 06 28 版权声明 可以任意转载 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 无论是安装anbox还是waydroid都失败了 记录一下 里面首先是没有 dev binder的问题 那是因
  • set up ovn development env (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 07 08 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 编译ovs并启动ovs vswitchd https docs

随机推荐

  • Using lxd to do vlan test (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 08 15 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 客户说sriov虚机里收不着arp reply 他们的s
  • ovn metadata (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 08 25 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 客户描述虚机的metadata功能偶尔有问题 xff0c
  • 网络攻防实验 (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 08 29 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 测试环境 lxd容器 xff0c i3为中间攻击者所以在i3上
  • nova VirtualInterfaceCreateException (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 09 01 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 虚机有时候会报下列错误 xff1a nova excep
  • ovn-central raft HA (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 10 12 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 What s raft RAFT https raft git
  • Linux(五):Ubuntu 16.04 更改系统语言为简体中文(Chinese simplified)

    Linux xff08 五 xff09 xff1a Ubuntu 16 04 更改系统语言为简体中文 xff08 Chinese simplified xff09 文章目录 1 问题2 设置中文2 1 设置 xff1b 2 2 点击 Ins
  • juju创建lxd容器时如何使用本地镜像(by quqi99)

    作者 xff1a 张华 发表于 xff1a 2023 03 01 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 没有外网 xff0c 所以配置了一个local cust
  • my cloud test bed (by quqi99)

    作者 张华 发表于 2023 03 10 版权声明 可以任意转载 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 有一台NUC minipc 配置是 CPU i7 13700H 16核20线程 内存 16G 32G 4
  • try chatgpt api (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2023 03 23 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 chatgpt web 试了网上的一个chatgpt web
  • ubuntu操音量调整命令amixer

    1 解除静音 sudo amixer set 39 Master 39 unmute sudo amixer set 39 Headphone 39 unmute sudo amixer set 39 Front 39 unmute 实际为
  • IAR软件应用中的错误提示

    1 Q xff1a Error e16 Segment XDATA Z size 0x19a1 align 0 is too long for segment definition At least 0xe4c more bytes nee
  • 软件工程—结构化分析设计

    进行完需求分析 xff0c 下一步该进行系统结构分析和设计了 现在主流的设计理念为结构化开发和面向对象开发 xff0c 本次主要讲解结构化开发 结构化开发分为结构化分析和设计两个阶段 结构化分析是面向数据流的分析方法 xff0c 基本思想是
  • 项目流标了怎么办?

    公开招标的项目如果出现流标现象 xff0c 是不能直接采取议标的方式 xff0c 或者直接采取竞争性谈判 单一来源采购 询价等非招标方式 xff0c 而应当组织二次招投标 xff0c 如果二次招标后仍然流标的 xff0c 可以核准后不再招标
  • xubuntu 14.04 LTS安装拼音输入法

    一 xff0c 安装fcitx sudo apt get install fcitx table wbpy 是不是很好记的样子 xff0c wb五笔py拼音 二 xff0c 配置fcitx desktop gnome language se
  • 整理库函数依赖关系

    问题 xff1a 现有一函数库 xff0c 这里是lapack3 5 lapack提供的每一个函数API都单独是一个 c 请给出这些API的相互调用关系 间接调用也要统计 xff0c 循环调用 xff08 如果可能的话 xff09 不计 进
  • 手把手教你写出正确的二分搜索!

    写出正确的二分搜索知易行难 xff0c 原理好像都懂 xff0c 但是实际上手就出各种错误 xff0c 例如如何确定循环终止条件 区间搜小判断条件等 这里就手把手教你写出正确的二分检索 xff01 二分法共有下面7种变式 是否存在数字t 返
  • SphereFace: Deep Hypersphere Embedding for Face Recognition

    Weiyang Liu 1 Yandong Wen 2 Zhiding Yu 2 Ming Li 3 Bhiksha Raj 2 Le Song 1 1 Georgia Institute of Technology 2 Carnegie
  • 一文解答你关于“轨道问题”的所有疑问!(有环链表问题)

    问题描述 xff1a 给定一个链表 xff0c 返回链表开始入环的第一个节点 如果链表无环 xff0c 则返回 NULL 我看过很多博客 xff0c 对于最优解法的解释无非两个字 xff0c 神奇 xff0c 并没有说明如何构思出这样的思路
  • 从bt到dp的困惑

    每一个dp的背后都必然有一个bt bt的基础上加上记忆化搜索 xff0c 然后对问题的拆分由从上到下变成从下到上 xff0c 即可转化为dp 但绝不是所有的bt就天然的可以转化为dp 例如下面这个例子 leetCode 115题 xff0c
  • 教练,我想学二叉树遍历!

    二叉树具有前序 中序 后序三种遍历方式 递归的相信大家都会写 xff0c 但是迭代的该怎么写呢 xff1f 怎样的迭代写法才能具有统一性便于理解呢 xff1f 请看下面具体的做法 xff0c 每种遍历方式各有2种策略 xff0c 基于栈的和