使用递归和非递归方式实现二叉树先序、中序、后序遍历

news2024/9/27 7:22:06

题目:

用递归和非递归方式,分别按照二叉树先序、中序和后续打印所有的节点。先序为根左右,中序为左根右,后序为左右根。

递归方式:

(1)先序:

    //先序 根左右
    public static void preOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        System.out.println(head.value + " ");
        preOrderRecur(head.left);
        preOrderRecur(head.right);
    }

 (2)中序:

    //中序 左根右
    public static void inOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left);
        System.out.print(head.value + " ");
        inOrderRecur(head.right);
    }

(3)后序:

 

    //后序 左右根
    public static void postOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        postOrderRecur(head.left);
        postOrderRecur(head.right);
        System.out.print(head.value + " ");
    }

测试结果:

    public static void main(String[] args) {
        Node head = new Node(1);
        Node node1 = new Node(2);
        Node node2 = new Node(3);
        Node node3 = new Node(4);
        Node node4 = new Node(5);
        Node node5 = new Node(6);

        head.left = node1;
        head.right = node2;
        node1.left = node3;
        node1.right = node4;
        node2.right = node5;

        preOrderRecur(head);
        System.out.println();
        inOrderRecur(head);
        System.out.println();
        postOrderRecur(head);
}

结果:

 非递归方式:

(1)先序:

具体过程如下:

(1)申请一个新的栈,记为stack,然后将头节点head压入栈中。

(2)从stack中弹出栈顶节点,记为cur,然后打印cur节点的值,再将节点cur的右孩子(不为空)入栈,最后将cur的左孩子(不为空的话)入栈。

(3)不断重复(2)过程,直到stack为空。

代码实现:

    //非递归先序
    public static void preOrderUnRecur(Node head) {
        System.out.print("非递归先序:");
        if (head != null) {
            Stack<Node> stack = new Stack<>();
            stack.add(head);
            while (!stack.isEmpty()) {
                head = stack.pop();
                System.out.print(head.value + " ");
                if (head.right != null) {
                    stack.push(head.right);
                }
                if (head.left != null) {
                    stack.push(head.left);
                }
            }
        }
    }

(2)中序:

具体过程如下:

(1)申请一个新的栈,记为stack,初始时,令变量cur=head。

(2)先把cur节点压入栈,对以cur节点为头节点的整颗子树来说,依次把左边界压入栈中,即不停的令 cur = cur.left,然后重复步骤(2)。

(3)不断重复步骤2,直到发现cur为空,此时从 stack 中弹出一个节点,记为 node,打印node的值,并且让 cur = node.right,(这里注意,让cur=node.right的时候,cur的值已经打印了,也就是根的值已经打印了,所以可以保证根在右前面打印)然后继续重复步骤2。

(4)当stack为空且cur为空时,整个过程停止。

 代码实现:

    //非递归中序
    public static void inOrderUnRecur(Node head) {
        System.out.print("非递归中序:");
        if(head != null) {
            Stack<Node> stack = new Stack<>();
            while (!stack.isEmpty() || head != null) {
                //先把左子树都放进栈
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                } else {
                    head = stack.pop();
                    System.out.print(head.value + " ");
                    head = head.right;
                }
            }
        }
    }

(3)后序:

具体过程:

(1)申请一个栈记为 stack1,然后将头节点head压入stack1中。

(2)从stack1中弹出的节点记为cur,然后依次将cur的孩子节点和孩子节点压入stack1中。(先左后右

(3)在整个过程中,每一个从stack1弹出的节点都放入 stack2中。

(4)不断重复(2)(3),直到s1为空,过程停止。

(5)从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。

每颗子树的头节点先从stack1弹出到stack2,然后把它的孩子从左到右压入到stack1,再从stack1中弹出的顺序就是先右再左,从stack1弹出的顺序就是 根 右 左,stack2与stack1相反,所以就是左右根。

 代码实现:

    //非递归后序
    public static void postOrderUnRecur(Node head) {
        System.out.print("非递归后序:");
        if (head != null) {
            Stack<Node> stack1 = new Stack<>();
            Stack<Node> stack2 = new Stack<>();
            stack1.push(head);
            while (!stack1.isEmpty()) {
                head = stack1.pop();
                stack2.push(head);
                if (head.left != null) {
                    stack1.push(head.left);
                }
                if (head.right != null) {
                    stack1.push(head.right);
                }
            }
            while (!stack2.isEmpty()) {
                System.out.print(stack2.pop().value + " ");
            }
        }
    }

测试结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/131131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TypeScript入门

这两天终于抽空学习了typescript&#xff0c;把欠了四年的帐给补上了。 废话不多说&#xff0c;先上官网链接&#xff1a;TypeScript中文网 TypeScript——JavaScript的超集 一、下载安装&#xff1a;用npm > npm install -g typescript 验证是否安装成功&#xff1a; …

保存网页内容 自动过滤广告和网页头尾

网页可以非常方便的为我们展示各种信息&#xff0c;如果遇到重要的资料文献&#xff0c;希望在本地电脑上保存下来该怎么操作呢&#xff1f;把网址添加到收藏夹&#xff0c;下次直接打开网址查看&#xff0c;但如果资源被网站删除&#xff0c;就再也找不到了。还是保存在自己电…

msf联动cs

Cobalt Strike简称CS 用于团队作战使用&#xff0c;由一个服务端和多个客户端组成&#xff0c;能让多个攻击者这在一个团队服务器上共享目标资源和信息&#xff0c;我们在使用msf获得权限以后&#xff0c;可以将信息共享到cs上&#xff0c;使用cs来进行监听以及其他的操作。 1…

理解Kotlin泛型

文章目录Kotlin泛型声明处型变协变< out T>逆变< in T>使用处型变(类型投影)参考Kotlin泛型 声明处型变 协变< out T> interface GenericsP<T> {fun get(): T //读取并返回T&#xff0c;可以认为只能读取T的对象是生产者 }如上声明了GenericsP<…

【C++】STL —— 用哈希表同时封装出unordered_set和unordered_map

目录 一、底层结构 1. 哈希的概念 二、哈希冲突 三、哈希函数 四、解决哈希冲突 1. 闭散列&#xff08;开放定址法&#xff09; 1. 线性探测 2. 二次探测 2. 闭散列的实现 3. 开散列&#xff08;拉链法&#xff09; 4. 开散列和闭散列的比较 五、HashTable的…

树莓派内核编译

文章参考&#xff1a; 深海游弋的鱼 – 默默的点滴 (mobibrw.com) 深海游弋的鱼 – 默默的点滴 (mobibrw.com) 1. 安装 git sudo apt install git 2. 下载树莓派内核源码 git clone --depth1 -b rpi-4.9.y https://github.com/raspberrypi/linux.git rpi-linux 3. 安装…

Python采集wangyi财经数据信息,做个可视化小案例

前言 2022年全球股市普跌&#xff0c;你亏了多少钱&#xff1f; 亏多少我也不知道&#xff0c;我只是想着来采集数据&#xff0c;做个可视化小案例来玩玩 话不多说&#xff0c;咱就直接开始吧 开发环境 解释器版本: python 3.8代码编辑器: pycharm 2021.2requests: pip ins…

Python笔记 | 卡布列克常数

0x00 前言 任意一个不是由完全相同数字组成的四位数&#xff0c;如果对它们的每位数字重新排序&#xff0c;组成一个较大的数和一个较小的数&#xff0c;然后用较大数减去较小数&#xff0c;差不够四位数时补零&#xff0c;类推下去&#xff0c;最后将变成一个固定的数&#xf…

使用kubeadm安装kubernetes记录

1.查看版本信息 # 在 master 节点和 worker 节点都要执行 cat /etc/redhat-release# 此处 hostname 的输出将会是该机器在 Kubernetes 集群中的节点名字 # 不能使用 localhost 作为节点的名字 hostname# 请使用 lscpu 命令&#xff0c;核对 CPU 信息 # Architecture: x86_64 …

C语言指针全解

C语言指针全解指针的定义指针的大小指针类型指针类型意义野指针二级指针字符指针指针数组数组指针&数组名 VS 数组名应用数组参数、指针参数函数指针函数指针数组函数指针数组的使用 - 模拟计算器指向函数指针数组的指针回调函数回调函数的使用 - qsort函数指针的定义 在计…

澳亚集团在港交所上市:IPO首日破发,毛利率走低,盈利能力下滑

12月30日&#xff0c;澳亚集团有限公司&#xff08;下称“澳亚集团”&#xff0c;HK:02425&#xff09;在港交所上市。本次上市&#xff0c;澳亚集团的发行价为6.40港元/股&#xff0c;发行数量为3064万股&#xff0c;募资总额约为1.96亿港元&#xff0c;募资净额约为1.01亿港元…

DoIP协议从入门到精通——DoIP企业规范常见疑问解答

基于自己在做DoIP测试过程中遇到的一些让自己困惑的点,汇总后与你分享,期望有所帮助。 具体内容如下: 1、IP地址 背景信息: 在通常Tester与车辆进行诊断通信时,Tester端设置好自己的IP地址信息,而对于待测ECU IP地址信息通常不设置,或者说不知道怎么设置。 穿拖鞋的…

ext4 extent详解1之示意图演示

本文将从内核源码、实例演示等角度详细ext4 extent B树的前世今生&#xff0c;希望看过本文的读者从理解ext4 extent的工作原理。内核版本3.10.96&#xff0c;详细内核详细源码注释见GitHub - dongzhiyan-stack/kernel-code-comment: 3.10.96 内核源代码注释。 1 ext4 extent由…

题库自定义配置,满足各种使用习惯,专治强迫症

目录 自定义题型 自定义选项 章节、难度增加排序属性 下一个版本预告 根据吐槽社区的反馈情况&#xff0c;没想到居然有台湾同胞使用土著刷题微信小程序&#xff0c;鉴于与内地的试题题目有所不同&#xff0c;所以土著刷题微信小程序v1.9主要迭代了题库自定义相关配置。 自…

架构师课程笔记day03——单体应用开发过程中常用知识点及注意事项

1.自定义异常捕获处理 定义如下类 可捕获并处理相关异常 package com.imooc.exception;import com.imooc.utils.IMOOCJSONResult; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;…

第十二篇 1+X考证 Web前端测试题PHP篇(新)

单选题 1、以下关于PHP面向对象的说法错误的是&#xff08; A &#xff09; A、PHP可以多重继承&#xff0c;一个类可以继承多个父类 B、PHP使用new运算符来获取一个实例对象 C、一个类可以在声明中用extends关键字继承另一个类的方法和属性 D、PHP默认将var关键字解释为pu…

数据源支持

数据源支持目录概述需求&#xff1a;设计思路实现思路分析1.AT模式2.TCC模式3.Saga模式4.XA模式参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for ch…

【ROS】—— ROS快速上手

文章目录前言1. ROS-melodic 安装2. ROS基本操作2.1 创建工作空间2.2 创建功能包2.3 HelloWorld(C版)2.4 HelloWorld(Python版)3. Vscode ROS 插件4. vscode 使用基本配置4.1 启动 vscode4.2 vscode 中编译 ros5. launch文件演示6. ROS文件系统7. ROS文件系统相关命令前言 &…

沸腾过程气泡成核OVITO渲染

《Lammps空间划分——识别气泡、三维裂隙》 根据博文对纳米气泡的筛选&#xff08;获得select&#xff09;&#xff0c;本案例练习如何渲染气泡。 文章目录一、选择气泡&#xff08;select&#xff09;二、删除液体三、渲染液体四、巧妙利用原子半径大小五、气泡渲染并获得体积…

elasticsearch 7.9.3知识归纳整理(一)之es,kibana,ik的下载安装

es&#xff0c;kibana&#xff0c;ik的下载安装 下载地址 es下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch kibana下载地址&#xff1a; https://www.elastic.co/cn/downloads/kibana ik中文分词器下载地址&#xff1a;https://github.com/medcl/el…