当前位置: 首页 > news >正文

[LeetCode] Binary Tree Preorder Traversal 二叉树的先序遍历

Given a binary tree, return the preorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?

一般我们提到树的遍历,最常见的有先序遍历,中序遍历,后序遍历和层序遍历,它们用递归实现起来都非常的简单。而题目的要求是不能使用递归求解,于是只能考虑到用非递归的方法,这就要用到stack来辅助运算。由于先序遍历的顺序是"根-左-右", 算法为:

1. 把根节点push到栈中

2. 循环检测栈是否为空,若不空,则取出栈顶元素,保存其值,然后看其右子节点是否存在,若存在则push到栈中。再看其左子节点,若存在,则push到栈中。

代码如下:

解法一:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if (!root) return {};
        vector<int> res;
        stack<TreeNode*> s{{root}};
        while (!s.empty()) {
            TreeNode *t = s.top(); s.pop();
            res.push_back(t->val);
            if (t->right) s.push(t->right);
            if (t->left) s.push(t->left);
        }
        return res;
    }
};

下面这种写法使用了一个辅助结点p,这种写法其实可以看作是一个模版,对应的还有中序和后序的模版写法,形式很统一,方便于记忆。辅助结点p初始化为根结点,while循环的条件是栈不为空或者辅助结点p不为空,在循环中首先判断如果辅助结点p存在,那么先将p加入栈中,然后将p的结点值加入结果res中,此时p指向其左子结点。否则如果p不存在的话,表明没有左子结点,我们取出栈顶结点,将p指向栈顶结点的右子结点,参见代码如下:

解法二:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode *p = root;
        while (!s.empty() || p) {
            if (p) {
                s.push(p);
                res.push_back(p->val);
                p = p->left;
            } else {
                TreeNode *t = s.top(); s.pop();
                p = t->right;
            }
        }
        return res;
    }
};

本文转自博客园Grandyang的博客,原文链接:二叉树的先序遍历[LeetCode] Binary Tree Preorder Traversal ,如需转载请自行联系原博主。

相关文章:

  • 实用算法实现-第 24 篇 高精度整数运算
  • PHP Mysql-插入多条数据
  • Windows窗体
  • DataWorks新手引导(持续更新)
  • TOP语句放到表值函数外,效率异常低下
  • 产品经理教你玩转阿里云负载均衡SLB系列(一):快速入门--什么是负载均衡
  • Enum一点使用总结
  • 路由器相关参数及设置
  • 祝网友们龙年快乐!
  • CSS以图换字的9种方法
  • 部署Oracle 11.2.0.3 RAC (二)
  • [WinForm]DataGridView通过代码新增行问题
  • linux下配置SS5(SOCK5)代理服务
  • Spring.net 学习笔记之ASP.NET底层架构
  • stagefright框架 Video Playback的流程
  • [PHP内核探索]PHP中的哈希表
  • Akka系列(七):Actor持久化之Akka persistence
  • JAVA 学习IO流
  • JS专题之继承
  • leetcode46 Permutation 排列组合
  • ubuntu 下nginx安装 并支持https协议
  • Webpack 4 学习01(基础配置)
  • 当SetTimeout遇到了字符串
  • 构造函数(constructor)与原型链(prototype)关系
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 前端面试之闭包
  • 区块链共识机制优缺点对比都是什么
  • 使用SAX解析XML
  • 提醒我喝水chrome插件开发指南
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 一起参Ember.js讨论、问答社区。
  • 阿里云服务器购买完整流程
  • #define 用法
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (第二周)效能测试
  • (定时器/计数器)中断系统(详解与使用)
  • (二)JAVA使用POI操作excel
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)Unity3DUnity3D在android下调试
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .Net7 环境安装配置
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET业务框架的构建
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • :O)修改linux硬件时间