java算法学习索引之二叉树问题

news2024/12/29 0:12:30

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

用递归和非递归方式,分别按照二叉树先序、中序和后序打印所有的节点。我们约定:先序遍历顺序为根、左、右;中序遍历顺序为左、根、右;后序遍历顺序为左、右、根。

递归方式

// 递归方式进行先序遍历
public void preorderRecursive(TreeNode root) {
    if (root == null) return;
    System.out.print(root.val + " "); // 打印当前节点
    preorderRecursive(root.left); // 递归遍历左子树
    preorderRecursive(root.right); // 递归遍历右子树
}

// 递归方式进行中序遍历
public void inorderRecursive(TreeNode root) {
    if (root == null) return;
    inorderRecursive(root.left); // 递归遍历左子树
    System.out.print(root.val + " "); // 打印当前节点
    inorderRecursive(root.right); // 递归遍历右子树
}

// 递归方式进行后序遍历
public void postorderRecursive(TreeNode root) {
    if (root == null) return;
    postorderRecursive(root.left); // 递归遍历左子树
    postorderRecursive(root.right); // 递归遍历右子树
    System.out.print(root.val + " "); // 打印当前节点
}

非递归方式,用堆栈

public void preOrderUnRecur(Node head) {
    System.out.println("pre-order:");
    if (head != null) {
        Stack<Node> stack = new Stack<Node>();
        stack.add(head);
        while (!stack.isEmpty()) {
            head = stack.pop();
            System.out.println(head.value + " "); // 打印当前节点

            // 先将右子节点入栈,再将左子节点入栈,保证弹出时的顺序是先左后右
            if (head.right != null) {
                stack.push(head.right);
            }
            if (head.left != null) {
                stack.push(head.left);
            }
        }
    }
    System.out.println();
}

public void inOrderUnRecur(Node head) {
    System.out.println("in-order:");
    if (head != null) {
        Stack<Node> stack = new Stack<Node>();
        while (!stack.isEmpty() || head != null) {
            if (head != null) {
                stack.push(head);
                head = head.left; // 将左子节点入栈
            } else {
                head = stack.pop();
                System.out.println(head.value + " "); // 打印当前节点
                head = head.right; // 遍历右子树
            }
        }
    }
    System.out.println();
}

public void posOrderUnRecur1(Node head) {
    System.out.println("post-order:");
    if (head != null) {
        Stack<Node> s1 = new Stack<Node>();
        Stack<Node> s2 = new Stack<Node>();
        s1.push(head);
        while (!s1.isEmpty()) {
            head = s1.pop();
            s2.push(head);

            // 先将右子节点入栈,再将左子节点入栈,保证弹出时的顺序是先左后右,进入s2时就是先右后左
            if (head.right != null) {
                s1.push(head.right);
            }
            if (head.left != null) {
                s1.push(head.left);
            }
        }
        while (!s2.isEmpty()) {
            System.out.println(s2.pop().value + " "); // 打印当前节点
        }
    }
    System.out.println();
}

public void posOrderUnRecur2(Node h) {
    System.out.println("post-order:");
    if (h != null) {
        Stack<Node> s1 = new Stack<Node>();
        s1.push(h);
        Node cNode = null;
        while (!s1.isEmpty()) {
            cNode = s1.peek();
            if (cNode.left != null && h != cNode.left && h != cNode.right) {
                s1.push(cNode.left); // 将左子节点入栈
            } else if (cNode.right != null && h != cNode.right) {
                s1.push(cNode.right); // 将右子节点入栈
            } else {
                System.out.print(s1.pop().value + " "); // 打印当前节点
                h = cNode;
            }
        }
    }
    System.out.println();
}

这些函数都使用了栈来模拟递归过程。具体来说:

  • preOrderUnRecur函数使用栈来模拟先序遍历的过程,先将根节点入栈,并在循环中弹出节点并打印,先将右子节点入栈,再将左子节点入栈。
  • inOrderUnRecur函数使用栈来模拟中序遍历的过程,始终将左子节点入栈,直到没有左子节点,然后弹出节点并打印,再将右子节点入栈。
  • posOrderUnRecur1函数使用两个栈来模拟后序遍历的过程,最终打印第二个栈中的节点,具体过程是先将根节点入栈1,然后循环中弹出节点并入栈2,先将左子节点入栈1,再将右子节点入栈1。
  • posOrderUnRecur2函数使用单个栈来模拟后序遍历的过程,通过判断当前节点的左右子节点和上一个弹出的节点来确定是否打印当前节点

二  打印二叉树的边界节点

【题目】

给定一棵二叉树的头节点head,按照如下两种标准分别实现二叉树边界节点的逆时针打印。

标准一:1.头节点为边界节点。

              2.叶节点为边界节点。3.如果节点在其所在的层中是最左的或最右的,那么该节点也是边界节点。

标准二:

             1.头节点为边界节点。

             2.叶节点为边界节点。

             3.树左边界延伸下去的路径为边界节点。

             4.树右边界延伸下去的路径为边界节点。例如,如图3-2所示的树。

按标准一的打印结果为:

1,2,4,7,11,13,14,15,16,12,10,6,3

按标准二的打印结果为:1,2,4,7,13,14,15,16,10,6,3

【要求】

1.如果节点数为N,两种标准实现的时间复杂度要求都为O(N),额外空间复杂度要求都为O(h),h为二叉树的高度。

2.两种标准都要求逆时针顺序且不重复打印所有的边界节点。

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

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

相关文章

FIB表与快速转发表实验

实验名称&#xff1a;FIB表与快速转发表实验 网络拓扑图&#xff1a; 实验步骤&#xff1a; 1、配置接口的IP地址 R1&#xff1a; R2&#xff1a; 2、配置OSPF路由协议 在R1宣告网段 在R2宣告网段 3、查看邻居状态&#xff0c;一直处于2-way状态&#xff0c;要等待30秒&…

在SOLIDWORKS中如何提升保存PDF版本文件的清晰度

随着Solidworks年复一年的不断更新&#xff0c;不仅仅是整个软件的性能上的提升&#xff0c;其在输出文件的功能上也同样在精益求精。 但对于老版本的使用者和希望能让输出文件清晰度更进一步的使用者而言&#xff0c;可能目前我们所能达到的普通文件输出清晰度远远无法达到他们…

内衣洗衣机哪些品牌质量好实惠?小型洗衣机全自动

现在洗内衣内裤也是一件较麻烦的事情了&#xff0c;在清洗过程中还要用热水杀菌&#xff0c;还要确保洗衣液是否有冲洗干净&#xff0c;还要防止细菌的滋生等等&#xff0c;所以入手一款小型的烘洗全套的内衣洗衣机是非常有必要的&#xff0c;专门的内衣洗衣机可以最大程度减少…

编译QT Mysql库并集成使用

安装MSVC编译器与Windows 10 SDK 打开Visual Studio Installer&#xff0c;如果已经安装过内容了可能是如下页面&#xff0c;点击修改&#xff08;头一回打开的话不需要这一步&#xff09;&#xff1a; 然后在工作负荷中勾选使用C的桌面开发&#xff0c;它会帮我们勾选好一些…

Modbus转Profinet改变局面,PLC与电力仪表秒级响应

Modbus转Profinet改变了传统的局面&#xff0c;实现了PLC与电力仪表之间的秒级响应。在过去&#xff0c;由于Modbus通信协议的限制&#xff0c;PLC与电力仪表之间的数据传输速度受到了很大的限制&#xff0c;无法满足工业自动化领域对实时性的要求。然而&#xff0c;随着Modbus…

【TypeScrpt算法】算法的复杂度分析

算法的复杂度分析 什么是算法复杂度&#xff1f; 不同的算法&#xff0c;其实效率是不一样的 让我举一个案例来比较两种不同的算法在查找数组中给定元素的时间复杂度 [1,2,3,4,5,6,7,...9999,n] 顺序查找 这种方法从头到尾遍历整个数组&#xff0c;依次比较每个元素和给定元…

SpringBoot项目启动后自动停止了?

1 现象 2023-11-22T09:05:13.36108:00 DEBUG 17521 --- [ main] o.s.b.a.ApplicationAvailabilityBean : Application availability state LivenessState changed to CORRECT 2023-11-22T09:05:13.36208:00 DEBUG 17521 --- [ main] o.s.b.a.Applicat…

解决Slf4J依赖冲突

项目启动&#xff0c;显示类路径包含多个 SLF4J 绑定&#xff0c;将其中一个排除即可。 找依赖 打开pom.xml&#xff0c;在文件内容上&#xff0c;右键&#xff0c;选择 Diagrams -> show dependencies… &#xff0c;ctrl f 输入slf4j-simple 然后右键&#xff0c;选择s…

网站被攻击了怎么办,有什么办法防御攻击?

近年来&#xff0c;随着互联网发展&#xff0c;出现了各种各样的网站&#xff0c;web应用&#xff0c;网络极大方便了人们的生活&#xff0c;改变了人们生活方式。而随着网络的发展普及&#xff0c;网络安全问题也困扰着用户。 许多人都曾有过这样经历&#xff0c;网站上线后&…

738. Monotone Increasing Digits 968. Binary Tree Cameras

738. Monotone Increasing Digits An integer has monotone increasing digits单调递增数字 if and only if each pair of adjacent digits x and y satisfy x < y. Given an integer n, return the largest number that is less than or equal to n with monotone increa…

节能灯和led灯哪个更护眼?精选高品质的LED护眼台灯

节能灯和LED灯相比&#xff0c;我认为LED灯会更加护眼一些&#xff0c;不过想要更护眼建议选择LED的护眼台灯会更好&#xff01; 大家都知道光亮对于我们来说是非常重要的&#xff0c;尤其是夜晚的时候&#xff0c;往往要借助一些灯具来提供充足的照明。对于孩子而言&#xff0…

UML建模图文详解教程01——Enterprise Architect安装与使用

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Enterprise Architect概述 官方网站&#xff1a;https://www.sparxsystems.cn/products/ea/&#xff1b;图示如下&#xff1a; Enterprise Architect是一个全功能的、基于…

页面添加水印效果实现

页面效果&#xff1a; 源代码&#xff1a; <div id"water-wrapper"></div> <div><div>111111111111111111111111111111111111111111111111111111111111111111111111111111111111</div><div>1111111111111111111111111111111111…

非遗之光:十八数藏柏松数字保护的璀璨之路

随着数字技术的崛起&#xff0c;非物质文化遗产的保护进入了一个新的纪元。在这个时代的先锋中&#xff0c;十八数藏以其对传统工艺的数字保护而独领风骚。这是一条璀璨之路&#xff0c;通过数字技术的应用&#xff0c;为传统工艺注入了新的活力。 十八数藏柏松将数字创新融入传…

哈希表-set、map

当需要判断一个元素是否在集合中时&#xff0c;就使用哈希法 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。 哈希表中关键码就是数组的索引下标&#xff0c;然后通过…

【django+vue】连接数据库、登录功能

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【djangovue专栏】 1.【djangovue】项目搭建、解决跨域访问 【djangovue】连接数据库、登录功能 django连接数据库1.安装MySQL驱动程序2.创建数据库3.配置settings.py文件4.创建表5.添加数据 登录功能1.django实现…

sql语法大全

1&#xff0c;创建数据库 create database 数据库名字; 2,查看所有的数据库名称 show databases; MySQL服务器已有4个数据库&#xff0c;这些数据库都是MySQL安装时自动创建的。 information_schema 和 performance_schema 数据库分别是 MySQL 服务器的数据字典&#xff08;…

【2021集创赛】基于ARM-M3的双目立体视觉避障系统 SOC设计

本作品参与极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动。 团队介绍 参赛单位&#xff1a;上海电力大学 队伍名称&#xff1a;骇行队 总决赛奖项&#xff1a;二等奖 1.摘要 随着信息技术的发展&#xff0c;AGV&#xff08;Automated Guided Vehic…

状态设计模式是什么?什么是 State 状态设计模式?Python 状态设计模式示例代码

什么是 State 状态设计模式&#xff1f; 状态设计模式是一种行为型设计模式&#xff0c;它允许一个对象在其内部状态发生改变时改变其行为&#xff0c;使其看起来好像改变了其类。状态模式主要解决的问题是&#xff1a;当一个对象的行为取决于它的状态&#xff0c;并且在运行时…

如何写好科研论文

写好科研论文需要遵循以下步骤&#xff1a; 确定研究主题和目标&#xff1a;在开始撰写论文之前&#xff0c;你需要明确你的研究主题和目标。这有助于你更好地组织论文的内容&#xff0c;并确保你的论文能够准确地传达你的研究成果。做好文献调研&#xff1a;在撰写论文之前&a…