C++数据结构X篇_17_C++实现二叉树的非递归遍历(企业链表实现栈,利用栈的先进后出特点实现二叉树的非递归遍历)

news2024/10/12 22:31:06

本篇参考C++实现二叉树的非递归遍历进行整合介绍。
在C++数据结构X篇_14_二叉树的递归遍历(先序遍历、中序遍历、后续遍历方法介绍;举例;代码实现)中我们实现二叉树通过递归遍历实现了先序、中序与后续遍历,那么如何通过非递归遍历实现先序、中序与后续遍历呢?

文章目录

  • 1. 二叉树的非递归遍历规则
  • 2. 实现代码
    • 2.1 代码解析
    • 2.2 实现代码

1. 二叉树的非递归遍历规则

我们先看看非递归遍历规则,还是同样的二叉树。

在这里插入图片描述

  • 1、首先将二叉树根节点A放入栈中,并将节点是否打印标签设为false。

  • 2、再将节点A从栈中弹出,将其左右子树节点BF入栈,打印标签设为false,将A再次入栈,此时是否打印的标签设为true(注意这里三个节点入栈顺序与先序、中序与后续遍历方式有关,入栈顺序与遍历顺序正好相反,如果为先序遍历DLR,入栈顺序就应该为RLD)

  • 3、再从栈中取出栈顶元素并进行打印,重复2的步骤,本身与左右子树分别入栈,本身打印标签改为true,左右子树打印标签设为false。

  • 4、如果从栈中取出的栈顶元素标签为true,则直接打印,并取下一个栈中元素

参考下图对整个流程进行理解更为直观一些:
在这里插入图片描述

2. 实现代码

2.1 代码解析

此处采用企业链表实现栈,并利用栈的先进后出特点实现上述二叉树的非递归遍历,主要分为以下几部分:

  • 栈的定义与操作
  • 二叉树相关定义与操作
  • 二叉树创建与遍历

2.2 实现代码

#include <iostream>
using namespace std;

//栈的定义与操作
//节点
class linknode
{
public:
	linknode* next;
};
//自定义数据
class my_data
{
public:
	linknode* node;
	char data;
};
//链式栈
class linkstack
{
public:
	linknode head;
	int size;
};
//初始化栈
linkstack* init_linkstack()
{
	linkstack* stack = new linkstack;
	stack->head.next = NULL;
	stack->size = 0;
	return stack;
}
//入栈
void push_linkstack(linkstack* stack, linknode* data)
{
	data->next = stack->head.next;
	stack->head.next = data;
	stack->size++;
}
//出栈
void pop_linkstack(linkstack* stack)
{
	stack->head.next = stack->head.next->next;
	stack->size--;
}
//返回栈顶元素
linknode* top_linkstack(linkstack* stack)
{
	return stack->head.next;
}

//二叉树相关定义与操作
const int my_true = 1;
const int my_false = 0;
//定义二叉树节点
class binarynode
{
public:
	char ch;			 //节点数据域
	binarynode* lchild;  //左孩子
	binarynode* rchild;  //右孩子
};
//栈中的二叉树节点
class linktree
{
public:
	linknode node;
	binarynode* root;
	int flag;
};
//创建栈中二叉树节点
linktree* creat_linktree_node(binarynode* node, int flag)
{
	linktree* newnode = new linktree;
	newnode->root = node;
	newnode->flag = flag;
	return newnode;
}
//非递归遍历
void nonrecurision(binarynode* root)
{
	//创建栈
	linkstack* stack = init_linkstack();
	//把根节点放入
	push_linkstack(stack, (linknode*)creat_linktree_node(root, my_false));
	while (stack->size > 0)
	{
		//弹出栈顶元素
		linktree* node = (linktree*)top_linkstack(stack);
		pop_linkstack(stack);

		//弹出节点判断是否为空
		if (node->root == NULL)
		{
			continue;
		}

		if (node->flag == my_true)
		{
			cout << node->root->ch << "\t";
		}
		else  //改变压栈顺序即可改变遍历顺序
		{
			//当前节点左右子树入栈
			push_linkstack(stack, (linknode*)creat_linktree_node(node->root->rchild, my_false));
			push_linkstack(stack, (linknode*)creat_linktree_node(node->root->lchild, my_false));
			//当前节点入栈
			node->flag = my_true;
			push_linkstack(stack, (linknode*)node);
		}
	}
	cout << endl;
}

int main()
{
	//创建节点
	binarynode node1 = { 'A',NULL,NULL };
	binarynode node2 = { 'B',NULL,NULL };
	binarynode node3 = { 'C',NULL,NULL };
	binarynode node4 = { 'D',NULL,NULL };
	binarynode node5 = { 'E',NULL,NULL };
	binarynode node6 = { 'F',NULL,NULL };
	binarynode node7 = { 'G',NULL,NULL };
	binarynode node8 = { 'H',NULL,NULL };
	//建立节点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	//非递归先序遍历
	cout << "非递归先序遍历:" << endl;
	nonrecurision(&node1);
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

  1. 二叉树的非递归遍历思路、二叉树的非递归遍历代码实现

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

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

相关文章

Confluence 自定义博文列表

1. 概述 Confluence 自有博文列表无法实现列表自定义功能&#xff0c;实现该需求可采用页面中引用博文宏标签控制的方式 2. 实现方式 功能入口&#xff1a; Confluence →指定空间→创建页面 功能说明&#xff1a; &#xff08;1&#xff09;页面引用博文宏 &#xff08;…

标准化助推开源发展丨九州未来参编开源领域4项团体标准正式发布

在数字中国及数字经济时代的大背景下&#xff0c;开源逐步成为各行业数字化发展的关键模式。在开源产业迅速发展的同时&#xff0c;如何评估、规范开源治理成为行业极度关注的问题。 近日&#xff0c;中电标2023年第27号团体标准公告正式发布&#xff0c;九州未来作为起草单位…

云表:只需3步,让你搞懂低代码和传统开发有什么区别

自2014年Forrester明确提出低代码&#xff08;Low-Code&#xff09;概念以来&#xff0c;这个领域已经引起了广泛的关注&#xff0c;并逐渐受到越来越多的重视。近年来&#xff0c;低代码因为其低开发门槛、易用性等优点&#xff0c;赢得了众多投资研究机构和企业用户的青睐&am…

【Vue】终结v-model

v-model修饰符 .lazy 默认 v-model 是输入框内容每次改变都会更新数据 加了 .lazy 后,只有在输入框失去焦点时才会更新数据 例如输入用户名,只有离开输入框时才保存用户名 // 输入的时候不会立即加载&#xff0c;等失去焦点时会加载 <input v-model.lazy"msg"…

Python打造一个词云制作软件

文章目录 参数字典布局测试结果 参数字典 自从做了热榜的词云之后&#xff0c;就越来越觉得词云的表达力真的很强&#xff0c;所以合计是不是可以为WordCloud做一个界面&#xff0c;来更加直观地操作。 既然以WordCloud为核心&#xff0c;那么界面的组件自然要和WordCloud的参…

GEO生信数据挖掘(九)肺结核数据-差异分析-WGCNA分析(900行代码整理注释更新版本)

第六节&#xff0c;我们使用结核病基因数据&#xff0c;做了一个数据预处理的实操案例。例子中结核类型&#xff0c;包括结核&#xff0c;潜隐进展&#xff0c;对照和潜隐&#xff0c;四个类别。第七节延续上个数据&#xff0c;进行了差异分析。 第八节对差异基因进行富集分析。…

王道计算机考研 操作系统学习笔记篇章一:操作系统概念

目录 操作系统的概念 操作系统的功能和目标 操作系统的特征 并发 共享 虚拟 异步 操作系统的发展和分类 三大阶段 手工操作阶段 批次处理阶段—单道批处理系统 批处理阶段—多道批处理系统 操作系统分类 分时操作系统 实时操作系统 其他操作系统 操作系统的运行机制 预备知识 …

CV计算机视觉每日开源代码Paper with code速览-2023.10.18

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【语义分割】IDRNet: Intervention-Driven Relation Netw…

图像检索算法 计算机竞赛

文章目录 1 前言2 图像检索介绍(1) 无监督图像检索(2) 有监督图像检索 3 图像检索步骤4 应用实例5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 图像检索算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff…

PlatformIO在clion和vscode上的开发和使用,机器人开发嵌入式代码

vscode PlatformIO:2020年你还在用Arduino&#xff1f;&#xff1f;快开始用PlatformIO开发Esp8266/32、Arduino、STM32&#xff0c;十分钟亲测ESP8266 clion PlatformIO: clion platformio搭建 其他说明&#xff1a; 在vscode里使用platformio&#xff0c;可以选择开发的平台…

MySQL学习(七)——存储过程

文章目录 1. 基本语法2. 变量2.1 系统变量2.2 用户定义变量2.3 局部变量 3. 逻辑关系3.1 if3.2 参数3.3 case3.4 while3.4 repeat3.5 loop 4. 存储结构4.1 游标4.2 条件处理程序4.3 存储函数 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合&#xff0c;调用存储…

idea dubge 详细

目录 一、概述 二、debug操作分析 1、打断点 2、运行debug模式 3、重新执行debug 4、让程序执行到下一次断点后暂停 5、让断点处的代码再加一行代码 6、停止debug程序 7、显示所有断点 8、添加断点运行的条件 9、屏蔽所有断点 10、把光标移到当前程序运行位置 11、单步跳过 12、…

leetCode 214.最短回文串 + KMP

给定一个字符串 s&#xff0c;你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 示例 1&#xff1a; 输入&#xff1a;s "aacecaaa" 输出&#xff1a;"aaacecaaa"示例 2&#xff1a; 输入&#xff1a;s &…

【Java学习之道】JDBC API介绍与使用方法

引言 对于初学者来说&#xff0c;数据库编程可能听起来有些复杂&#xff0c;但实际上&#xff0c;只要你掌握了JDBC&#xff08;Java Database Connectivity&#xff09;API&#xff0c;就可以轻松地连接和操作数据库。本章将为你详细介绍JDBC API的概念、使用方法以及一些实际…

2023年信息院学生科协第二次硬件培训

2023年信息院学生科协第二次硬件培训 前言一、51单片机简介1、什么是单片机2、主流单片机及其编程语言3、单片机的应用4、单片机开发软件 二、GPIO&#xff08;点亮LED&#xff09;1、GPIO简介2、LED简介3、硬件设计4、软件设计 三、GPIO&#xff08;独立按键&#xff09;1、按…

ifndef是什么,如何使用?

引言 使用HbuilderX uni-ui模板创建的uni-app项目&#xff0c;main.js文件中看到有如下的注释&#xff1a; // #ifndef VUE3 ...... // #endif // #ifdef VUE3 ...... // #endif 相信很多没有uini-app项目开发经验的朋友&#xff0c;初次接触uni-app项目&#xff0c;可…

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现基于LSTM-Ada…

Android 虚拟 A/B 详解(十) 判断 Virtual A/B 是否打开的 5 种办法.md

文章目录 0. 导读1. Virtual A/B 的开关1.1 编译开关1.2 编译开关的定义位置1.3 编译开关的作用 2. Virtual A/B 开关检查方法 1. 从源码判断示例 1. Broadcom 平台示例 2. Google 平台 方法 2、从编译输出判断方法 3、从 image 镜像文件判断示例 1. 从 super.img 判断示例 2. …

强化学习(reinforcement)

B站链接 https://www.bilibili.com/video/BV13a4y1J7bw?p1&vd_source6f43d02eb274352809b90e8cdf744905 agent----------environment--------goal State 状态 Action 行动 Reward奖励 是一个及时的反馈 目标是一个长远的结果 Core element&#x1f447; Policy 策略…

jQuery实现简易购物车

购物车中的商品列表如下&#xff1a; 需求如下&#xff1a; &#xff08;1&#xff09;实现如图所示商品列表 &#xff08;2&#xff09;单击’移出’按钮可用删除商品 &#xff08;3&#xff09;单击’全选’按钮选中所有商品 &#xff08;4&#xff09;根据用户的选择&am…