【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解)

这篇具有很好参考价值的文章主要介绍了【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

 上篇:【算法与数据结构】二叉树的三种遍历代码实现(上)—— 用递归序知识点讲解_Hacynn的博客-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/133609612?spm=1001.2014.3001.5502

目录

前言

1、先序遍历

1.1、详细图解描述

1.2、先序遍历非递归代码实现 

2、中序遍历

2.1、详细图解描述 

2.2、中序遍历非递归代码实现  

3、后序遍历

3.1、详细图解描述 

3.2、后序遍历非递归代码实现   


【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

前言

        在上篇当中给大家介绍了二叉树的先序遍历、中序遍历以及后序遍历的递归写法。递归的系写法主要是理解递归序,只要递归序能够理解清楚,就能够很轻易地理解和书写递归实现三次遍历。

        任何递归函数都可以改成非递归函数,因为递归函数不是什么玄学,只是递归时系统帮忙解决了压栈问题。那么不用递归方式的话只要自己手动进行压栈依然可以完成递归能够实现的功能。

        那么在接下来的下篇中,我将带大家审深入学习二叉树三种遍历的非递归写法,也是二叉树遍历的代码中的重点内容,因为递归方式的代码非常好实现,因此在面试时常常会考大家的是非递归的写法。

1、先序遍历

先说结论:首先准备一个栈,将头结点入栈后,执行循环操作:

  1. 从栈中弹出一个结点记为cur。
  2. 对cur进行打印(或者是处理)操作。
  3. 如果cur有右孩子的话,则将cur的右孩子入栈。
  4. 如果cur有左孩子的话,则将cur的左孩子入栈。(即先右再左)注意区分此时的入栈顺序和递归实现遍历时的打印顺序的不同,不要搞混淆。
  5. 周而复始。

压栈顺序:头右左

1.1、详细图解描述

下面进行详细步骤描述: 

 首先先把头结点进栈,即1结点入栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

从栈中弹出一个结点记为cur,此时的cur即为1。对cur进行打印(或者其他处理)操作,如果cur有孩子的话,则将cur的右节点和左节点按右左顺序入栈。即此时 结点3结点2 入栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,再次从栈中弹出一个结点记为cur,此时的cur即为2。对cur进行打印(或者其他处理)操作,并将cur的孩子按右左顺序入栈。即此时 结点5结点4 入栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,栈中弹出结点4记为cur,打印cur,并压栈cur左右孩子结点,但是此时cur(也就是4结点)并没有左右孩子结点了,所以不进行压栈操作。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

 周而复始,栈中弹出结点5记为cur,打印cur,5和4一样没有孩子节点,所以不进行压栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,栈中弹出结点3记为cur,打印cur,将孩子结点6和7入栈。 

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

剩下的操作就都是周而复始的操作了,这里篇幅原因就不在演示了。可以看到打印出来的顺序就是先序遍历的顺序。

1.2、先序遍历非递归代码实现 

	public static void preOrderUnRecur(Node head) {
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();   //首先准备一个栈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. 先将整棵树的左边界的所有结点依次入栈。
  2. 依次从栈中弹出结点记为cur,并打印(或其他操作)cur。依次判断cur是否有右子树,有则将右子树的整棵树左边界的所有结点依次入栈。
  3. 周而复始。

压栈顺序:(左全)右

2.1、详细图解描述 

 下面进行详细步骤描述:  

 首先将整颗数的左边界依次入栈,即1,2,4。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

从栈用弹出结点4记为cur,打印cur并判断右子树是否存在,此时没有则继续从栈用弹出结点2记为cur并打印。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

判断cur的右子树是否存在,此时右子树存在,则以结点5为整棵树的头结点,将整棵树的左边界的所有结点依次入栈,这里的左边界只有5结点一个,即将5结点入栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

从栈用弹出结点5记为cur,打印cur,此时cur不存在右子树,则继续从栈中弹出结点1记为cur并打印。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

此时cur(即结点1)存在右子树,则以结点3为整棵树的头结点,将整棵树的左边界的所有结点依次入栈,即3和6。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

继续从栈中弹出结点6记为cur并打印,此时结点6没有右子树,则继续从栈中弹出结点3并打印。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

最后结点3存在右子树,右子树的左边界只有7,将7入栈。然后从栈中弹出7并打印,7没有孩子节点,不操作。当再从栈中弹出结点时发现已空,则结束循环。 

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

2.2、中序遍历非递归代码实现  

	public static void inOrderUnRecur(Node head) {
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();    //栈stack
			while (!stack.isEmpty() || head != null) { //栈不为空或者此时的头结点不为空
				if (head != null) {
                    //如果head不为空,则入栈,然后head指向下一个左孩子结点,继续判断是否为空,不为空继续执行
					stack.push(head);
					head = head.left;
				} else {
                    //当为空时从栈中弹出结点head,然后打印出head,并将head指向head的右孩子结点
					head = stack.pop();
					System.out.print(head.value + " ");
					head = head.right;
				}
			}
		}
	}

3、后序遍历

先说结论:首先准备两个栈(一个遍历栈,一个收集栈),将头结点压栈进遍历栈后,执行循环操作:

  1. 遍历栈中弹出一个结点记为cur。
  2. 将cur压栈进收集栈中。
  3. 如果cur有左孩子的话,则将cur的左孩子压栈进遍历栈。
  4. 如果cur有右孩子的话,则将cur的右孩子压栈进遍历栈。(即先左再右),注意与先序非递归遍历进行区分。
  5. 周而复始。

最后当遍历栈中再无结点时,将收集栈中的内容全部出栈,出栈顺序即为后序遍历顺序。

压栈顺序:头左右

3.1、详细图解描述 

 下面进行详细步骤描述: 

首先先把头结点入遍历栈,即1结点入遍历栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

遍历栈中弹出一个结点记为cur,此时的cur即为1。然后将cur入收集栈。如果cur有孩子的话,则将cur的左节点和右节点按左右顺序入遍历栈。即此时 结点2结点3 入遍历栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,从遍历栈中弹出一个结点记为cur,此时的cur即为3。然后将cur入收集栈。如果cur有孩子的话,则将cur的左节点和右节点按左右顺序入遍历栈。即此时 结点6结点7 入遍历栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,从遍历栈中弹出结点7记为cur,然后将cur入收集栈。此时cur没有左右孩子,所以不操作。

接下来的结点6也和结点7一样,从遍历栈中弹出后直接入收集栈

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

周而复始,从遍历栈中弹出结点2记为cur,然后将cur入收集栈。将cur的孩子结点4,5分别入遍历栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

最后遍历栈中的5和4都没有孩子结点,因此全部出栈并入收集栈。

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

此时将收集完的收集栈依次出栈并打印,得到的序列就是后序遍历

【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

3.2、后序遍历非递归代码实现   

	public static void posOrderUnRecur(Node head) {
		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);     //将出栈结点入收集栈
				if (head.left != null) {    //当左孩子存在时入遍历栈
					s1.push(head.left);
				}
				if (head.right != null) {   //当右孩子存在时入遍历栈(必须遵循先左后右的入栈顺序)
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {     //当遍历栈结束后,将收集栈中的所有结点挨个打印
				System.out.print(s2.pop().value + " ");
			}
		}
	}

 【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解),算法与数据结构,数据结构,算法,开发语言,java,intellij-idea

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!文章来源地址https://www.toymoban.com/news/detail-713634.html

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

到了这里,关于【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】二叉树的遍历递归算法详解

    我们来写一个函数 BuyNode(x)函数 用于创建二叉树结点。 用动态开辟函数 malloc 函数进行动态开辟,并强制转换为 BTNode 型,用变量 node 来去管理开辟的空间。 我们初始化结点,其 val 即为传入的参数x,左右指针 left 和 right 都设为NULL。 我们在主函数中创建上面这样一颗二叉树

    2024年01月20日
    浏览(45)
  • 【数据结构和算法15】二叉树的实现

    二叉树是这么一种树状结构:每个节点最多有两个孩子,左孩子和右孩子 重要的二叉树结构 完全二叉树(complete binary tree)是一种二叉树结构,除最后一层以外,每一层都必须填满,填充时要遵从先左后右 平衡二叉树(balance binary tree)是一种二叉树结构,其中每个节点的左

    2024年02月16日
    浏览(34)
  • 【数据结构与算法】二叉树的知识讲解

    目录  一,二叉树的结构深入认识  二,二叉树的遍历  三,二叉树的基本运算 3-1,计算二叉树的大小 3-2,统计二叉树叶子结点个数 3-3,计算第k层的节点个数 3-4,查找指定值的结点         二叉树是不可随机访问的,二叉树的结构是通过双亲结点与孩子结点之间的连接进

    2024年02月08日
    浏览(41)
  • 【数据结构】【算法】二叉树、二叉排序树、树的相关操作

    树结构是以分支关系定义的一种层次结构,应用树结构组织起来的数据,逻辑上都具有明显的层次关系。 操作系统中的文件管理系统、网络系统中的域名管理、数据库系统中的索引管理等都使用了树结构来组织和管理数据。 树 Tree 是由n个节点组成的有限集合。在任意一颗非

    2024年02月04日
    浏览(53)
  • 数据结构和算法学习记录——平衡二叉树(基本介绍、平衡因子、平衡二叉树的定义、平衡二叉树的高度)

    目录 基本介绍 平衡因子 平衡二叉树  平衡二叉树的高度  什么是平衡二叉树? 以一个例子来解释一下: 搜索树结点按不同的插入次序,将会导致不同的深度和平均查找长度ASL   在二叉搜索树中查找一个元素:  (a)要找到Jan,需要查找一次;要找到Feb,需要查找两次;

    2023年04月26日
    浏览(65)
  • 【数据结构与算法】力扣:二叉树的层序遍历

    给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例1: 输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 示例 2: 输入:root = [1] 输出:[[1]] 示例 3: 输入:root = [] 输出:[] 来源:力扣(LeetCode) 链接:https://leetcode.cn/p

    2024年02月13日
    浏览(46)
  • 数据结构与算法----详解二叉树的遍历(迭代、递归)

    ❤️ 作者简介 :大家好我是小鱼干儿♛是一个热爱编程、热爱算法的大三学生,蓝桥杯国赛二等奖获得者 🐟 个人主页 :https://blog.csdn.net/qq_52007481 ⭐ 个人社区 :【小鱼干爱编程】 🔥 算法专栏 :算法竞赛进阶指南 💯 刷题网站 :虽然市面上有很多的刷题网站,但是里面

    2024年01月24日
    浏览(54)
  • 数据结构与算法之二叉树: Leetcode 111. 二叉树的最小深度 (Typescript版)

    二叉树的最小深度 https://leetcode.cn/problems/minimum-depth-of-binary-tree/ 描述 就 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 示例 1 示例 2 提示 树中节点数的范围在 [0, 1 0 5 10^5 1 0 5 ] 内

    2024年02月06日
    浏览(44)
  • 【算法与数据结构】236、LeetCode二叉树的最近公共祖先

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 : 根据定义,最近祖先节点需要遍历节点的左右子树,然后才能知道是否为最近祖先节点。 那么这种需求是先遍历左右节点,然后遍历中间节点,属于左右中的后序遍历模式 。因此

    2024年02月09日
    浏览(39)
  • 数据结构——基于二叉树的表达式求值算法

    1.输入一个表达式(表达式中的数均小于10的正整数),利用二叉树来表示该表达式,创建表达式数,然后利用二叉树的遍历操作求表达式的值。 2.输入要求:多组数据,每组数据1行,为一个表达式,表达式以“=”结尾。当输入只有一个“=”时,输入结束。 3.输出要求:每组

    2024年02月04日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包