C++实现线索二叉树 -- 创建遍历查找等操作

数据结构(15.3)线索二叉树 中序线索二叉树的实现 阅读详情

本文代码为C++实现线索二叉树,文中所有代码均经过测试。

#ifndef _THREAD_BIN_TREE_H
#define _THREAD_BIN_TREE_H

#include <iostream>
#include <stack>
#include <assert.h>
using namespace::std;

typedef enum{LINK, THREAD}Tag;

template<typename _T>
class _Thread_Bin_Tree;

template<typename _T>
class _Tree_Node{
	friend class _Thread_Bin_Tree<_T>;
public:
	_Tree_Node() :m_data(_T()), leftChild(NULL), rightChild(NULL), ltag(LINK), rtag(LINK)
	{}
	_Tree_Node(_T data, _Tree_Node<_T>* left = NULL, _Tree_Node<_T>* right = NULL) 
				:m_data(data), leftChild(left), rightChild(left), ltag(LINK), rtag(LINK)
	{}
public:
	Tag ltag;
	Tag rtag;
	_T m_data;
	_Tree_Node<_T>  *leftChild;
	_Tree_Node<_T>  *rightChild;
};

template<typename _T>
class _Thread_Bin_Tree{
	typedef _Tree_Node<_T> node_type;
public:
	_Thread_Bin_Tree() = default;
	_Thread_Bin_Tree(const _T& ref) :refval(ref)
	{}
	~_Thread_Bin_Tree() {}
public:
	void init_bin_tree(const char *&);
	void inorder_thread();

	void inorder_traverse()const;

	node_type* First()const;
	node_type* Last()const;
	node_type *Prev(node_type *)const;
	node_type *Next(node_type *)const;
	node_type *Parent(node_type *)const;
protected:
	void init_bin_tree(node_type *&, const char *&);
	void inorder_thread(node_type *&, node_type *&);

	void inorder_traverse(node_type *)const;

	node_type* First(node_type *)const;
	node_type* Last(node_type *)const;
	node_type *Prev(node_type *, node_type *)const;
	node_type *Next(node_type*, node_type *)const;
	node_type *Parent(node_type*, node_type *)const;
private:
	_T refval;
	node_type *root; 
};

/************************************public interface******************************************/

template<typename _T>
void _Thread_Bin_Tree<_T>::init_bin_tree(const char *&str)
{
	init_bin_tree(root, str);
}

template<typename _T>
void _Thread_Bin_Tree<_T>::inorder_thread()
{
	node_type *pre = NULL;
	inorder_thread(root, pre);
	pre->rtag = THREAD;
}

template<typename _T>
void _Thread_Bin_Tree<_T>::inorder_traverse()const
{
	inorder_traverse(root);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::First()const
{
	return First(root);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Last()const
{
	return Last(root);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Prev(node_type *cur)const
{
	return Prev(root, cur);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Next(node_type *cur)const
{
	return Next(root, cur);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Parent(node_type *cur)const
{
	return Parent(root, cur);
}

/************************************protected interface***************************************/

template<typename _T>
void _Thread_Bin_Tree<_T>::init_bin_tree(node_type *&pt, const char *&str)
{
	if(*str == refval){
		pt = NULL;	
	}
	else{
		pt = new node_type(*str);
		init_bin_tree(pt->leftChild, ++str);
		init_bin_tree(pt->rightChild, ++str);
	}
}

template<typename _T>
void _Thread_Bin_Tree<_T>::inorder_thread(node_type *&pt, node_type *&pre)
{
	if(pt == NULL)
		return ;
	
	inorder_thread(pt->leftChild, pre);

	if(pt->leftChild == NULL){
		pt->ltag = THREAD;
		pt->leftChild = pre;
	}

	if(pre != NULL && pre->rightChild == NULL){
		pre->rtag = THREAD;
		pre->rightChild = pt;
	}

	pre = pt;
	inorder_thread(pt->rightChild, pre);
}

template<typename _T>
void _Thread_Bin_Tree<_T>::inorder_traverse(node_type *pt)const
{
	if(pt != NULL){
		while(pt != NULL){
			pt = First(pt);
			cout << pt->m_data << " "; 
		
			while(pt->ltag == THREAD && pt->rightChild != NULL){
				pt = pt->rightChild;
				cout << pt->m_data << " ";
			}
			
			pt = pt->rightChild;
		}
	}
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::First(node_type *pt)const
{
	assert(pt != NULL);
	
	while(pt->ltag == LINK)
		pt = pt->leftChild;
	return pt;
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Last(node_type *pt)const
{
	assert(pt != NULL);

	while(pt->rtag == LINK)
		pt = pt->rightChild;
	return pt;
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Prev(node_type *pt, node_type *cur)const
{
	assert(pt != NULL && cur != NULL && pt != cur);

	if(cur->ltag == THREAD)
		return cur->leftChild;
	else
		return Last(cur->leftChild);
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Next(node_type *pt, node_type *cur)const
{
	assert(pt != NULL && cur != NULL);

	if(cur->ltag == THREAD)
		return cur->rightChild;
	else
		return First(cur->rightChild);		
}

template<typename _T>
_Tree_Node<_T>* _Thread_Bin_Tree<_T>::Parent(node_type *pt, node_type *cur)const
{
	assert(pt != NULL && cur != NULL && pt != cur);

	if(cur->rtag == THREAD && cur->rightChild != NULL 
						   && cur->rightChild->leftChild == cur)
		return cur->rightChild;
	if(cur->ltag == THREAD && cur->leftChild->rightChild == cur)
		return cur->leftChild;

	node_type *tmp = Last(cur)->rightChild;
	if(tmp != NULL && tmp->leftChild->rightChild == cur)
		return tmp->leftChild;
	if(tmp != NULL && tmp->leftChild == cur)    //for B -> A
		return tmp;

	tmp = First(cur)->leftChild;
	if(tmp != NULL && tmp->rightChild == cur)
		return tmp;
}

#endif


数据结构实验二 一、实验目的 1、线性表的链表实现:遍历、查找、插入、删除、翻转 2、栈的链式存储结构实现:入栈、出栈 3、队列的链式存储结构的实现:入队、出队 4、线性表、栈和队列的应用实现 二、使用仪器、器材 微机一台 操作系统:WinXP 编程软件:C++ 三、实验内容及原理 利用二叉树的二叉链式存储结构设计并实现各种操作算法。 1、二叉树的基本操作算法实现 (1) 利用二叉树字符串“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”创建二叉树的二叉链式存储结构; (2) 输出该二叉树; ( 阅读详情

相关推荐

c++模板实现二叉树,线索化,线索化遍历,非递归遍历及一些基本操作

c++模板类实现二叉树一些基本操作:前中后 遍历 及其 非递归遍历。  二叉树线索化, 及线索化后采用非递归方式遍历。  层序遍历。  叶子结点个数, k层节点个数, 二叉树深度, 查找元素等。 两个头文件, 一个是线索化有关, 另一个是别的操作 BinaryTree: #ifndef BINARY_TREE_H_ #define BINARY_TREE_H_ //树

ssopp24的博客 1175

C++线索二叉树(先序/前序线索二叉树及遍历)

使用c++实现 先序/前序线索二叉树及其先序遍历

qq_58240448的博客 2761

二叉树之中序线索

遍历二叉树是以一定的规则将二叉树中结点排列成一个线性序列,

KEEP PERFECTING MYSELF 3250

线索二叉树的原理以及创建和遍历(c++)

这是一篇非常好的关于线索二叉树的文章,内容详细到位,叙述清晰。作者是以为很认真、信息的人,估计花了不少时间和精力,向作者致敬! 引用地址:http://waret.iteye.com/blog/709779 PROCEDURE INTHREAD(BT,h) IF BT != 0 THEN { INTHREAD(L(BT),h) I

wbcg111的专栏 4064

数据结构05:树与二叉树[C++][线索二叉树:中序]

本篇博文含{线索化的基本原理与中序线索化的代码},由于模板字数限制,先序、后序线索化的代码会放在下篇整理~🥝🥝

weixin_42789937的博客 2951

线索二叉树的插入,删除

一、内容 线索二叉树的应用。实现线索二叉树的建立、插入、删除、恢复线索的实现。

线索二叉树的建立与遍历C/C++

dzfdsf

g15827636417的博客 3581

线索二叉树的建立、删除、插入、恢复线索

线索二叉树的建立 删除 插入 恢复线索

线索二叉树的建立与遍历

概述 1,什么是线索二叉树? 用自己的话说就是:原来我们求一棵二叉树的前序、中序、后序序列的时候,都必须用到递归遍历相应的二叉树,否则也得借助栈等结构来记录。这样的话,如果我们想很快的找到某一个节点在某种序列下的前驱或后继,每次都要遍历,这显然十分浪费时间。很自然,要是想避免这个重复工作,那么我们就需要把所有节点的前驱和后继记录下来,这样每次查找相应的记录就行了。于是就引出了——‘线索’一词。没

razorEdge的博客 1万+

线索二叉树的遍历

线索二叉树的先序,中序,后序遍历完整代码,在vs2013下编译通过

线索二叉树的建立与实现

在查找比较经常的二叉树中,如果用普通的二叉树则会耗费较多的时间,为止我们考虑使用二叉树来提高效率。

c/c++实现线索二叉树及其中序遍历和查找

c/c++实现线索二叉树及其中序遍历和查找 #include #include typedef char DataType; typedef struct { int ltag,rtag; DataType data; struct node *lchild,*rchild; }ThreadNode,*ThreadTree; //inorder thr

min954584739的博客 1464

中序线索二叉树(建立二叉树,线索化,输出二叉树)

中序线索二叉树(建立二叉树,线索化,输出二叉树)

二叉树的操作

表示二叉树的基本操作,涵可运行代码

2401_87092242的博客 382

ArcMap安装与配置全攻略:从下载到实战应用

本文提供了ArcMap 10.4.1从系统准备、详细安装到破解激活的完整指南,并包含首次启动的界面介绍与一个实战GIS分析项目。针对初学者,文章强调了在ArcGIS Pro成为趋势的当下,学习经典ArcMap对于理解核心概念和兼容现有工作流仍有重要价值,帮助用户避开安装常见陷阱,快速上手实战应用。

weixin_29200741的博客 338

做量化没有实时数据怎么行?我找到一个超级好用的Python库,速度还贼快!

今天咱们介绍了 pytdx 这个神奇的库,重点包括:✅ 安装 pytdx✅ 连接 TDX 服务器✅ 获取实时行情数据✅ 获取 K 线数据✅ 获取分笔成交数据总之,pytdx 是一个速度快、免费、易用的量化利器,适合 A 股量化交易的同学们使用。如果你还在为数据发愁,赶紧试试吧!🚀顺手再看就是对花姐最大的支持,期待你的关注。

奔跑的蜗牛 5725

中序线索二叉树(构建,遍历和找前驱后继节点)附c++详细解释代码!

在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化 线索化二叉树的本质,实际上是对原始二叉树中的指向为空(NULL)的指针域进行利用,我们让其指向为NULL的指针域指向前驱(左孩子)或者是后继(右孩子),但是我们怎么来辨别是树节点还是指向其前驱还是后继呢? 核心思想: 我们为每一个树节点增加两...

One_castle的博客 5524

PSO算法介绍

结合网上的文章对PSO进行一些介绍,并附上自己复现的算法。

Witty_Hou的博客 1万+

C++实现树 - 05 线索二叉树

写在前面: 上一讲我们实现了代码量较大的二叉排序树,这一讲我们讲一个新的类型 —— 线索二叉树。这一讲代码量不多,但在理解上需要大家花一点功夫~ 思考 在我们之前学到的树中可以发现,一个拥有 N 结点的二叉树,它一定有 N-1 条边是指向节点的即有效分支,但是有 2N-(N-1) = N+1 条边是指向空指针域的,这就导致了空间上的浪费。 此外,当对二叉树进行中序遍历时可以得到二叉树的中序序列。如果所示,中序遍历的结果为 6 3 7 1 2 。但是,这种关系的获得是建立在完成遍历后得到的,那么可不可以.

Newin2020的博客 1790

解决PubMed卡在“正在检查浏览器”页面的完整排查指南

DNS解析是将域名转换为IP地址的基础网络服务,其稳定性和准确性直接影响网站访问。当DNS服务器响应缓慢或返回异常结果时,可能导致客户端与服务器建立连接时出现偏差,从而触发网站的安全验证机制,例如Cloudflare等安全服务提供的浏览器环境检查。这一机制旨在防御恶意流量,但偶尔也会误拦截正常访问。在生物医学信息检索领域,PubMed作为核心文献数据库,其稳定访问对科研工作流至关重要。针对因DNS或本地缓存问题导致的‘正在检查浏览器’页面卡顿,通过刷新DNS缓存、更换为Google Public DNS或C

weixin_29597551的博客 3640

告别ROS1!在Ubuntu 22.04上为VINS-Fusion适配ROS2 Humble的完整踩坑记录

本文详细记录了在Ubuntu 22.04上将VINS-Fusion从ROS1迁移到ROS2 Humble的完整过程,包括环境搭建、依赖管理、核心代码适配及性能优化。通过实战案例和调试技巧,帮助开发者高效解决迁移过程中的常见问题,提升系统稳定性和性能。

weixin_42628688的博客 281

线索二叉树的详细实现(C++)

线索二叉树概述 二叉树虽然是非线性结构,但二叉树的遍历却为二叉树的结点集导出了一个线性序列。如果我们希望很快找到某一结点的前驱或后继,但不希望每次都要对二叉树遍历一遍,这就需要把每个结点的前驱和后继信息记录下来。 为了做到这一点,可在原来的二叉链表中增加一个前驱指针域(pred)和一个后继指针域(succ),分别指向该结点在某种次序下的前驱结点和后继结点,但是这种方法将会导致很多结点中有没有利用的空指针,先看下面的例子。 比如:现在有一个结点数为 n 的二叉树,采用二叉链表形式存储。对于每个结点均有指向左右

code_peak 3825

你不必懂AI,但必须会用AI:写给所有焦虑中的职场人

AI时代不必焦虑学技术,关键在于用AI解决实际问题。文章指出,99%的人只需成为AI使用者而非建造者,核心竞争力在于结合业务痛点运用AI工具提升效率。与其盲目学习工具,不如梳理工作流程,识别可优化环节,让AI赋能重复性、标准化任务。行业经验与AI工具的结合才是真正的职场护城河。建议从具体工作场景出发,寻找匹配的AI解决方案,迈出应用第一步。

hundred98的博客 716

二叉树遍历与线索二叉树全解析

二叉树的遍历是指按照某种特定的顺序访问二叉树中的所有节点,使得每个节点恰好被访问一次。遍历操作在二叉树的许多应用中都起着关键作用,例如计算二叉树的节点数量、查找特定节点、实现二叉树的复制等。

m0_57836225的博客 837

自动分割和测量混凝土钢筋的思路与原理

该文提出了一种基于PCL库的点云处理系统,用于自动测量混凝土结构中钢筋的几何参数。系统采用多阶段处理流程:首先通过RANSAC算法提取地面并旋转对齐;接着使用区域生长算法分割混凝土结构;然后采用RANSAC线检测识别钢筋,按方向分类;最后通过圆柱拟合和坐标差计算获得钢筋间距、直径和高度差等参数。文章详细介绍了各模块的核心算法,包括地面检测、坐标变换、钢筋识别和几何计算等关键步骤,并分析了主要参数的敏感性。系统通过分层处理和坐标变换确保测量精度,为混凝土结构的无损检测提供了自动化解决方案。

weixin_45196569的博客 680

【Segment Anything Model】十(1):利用SAM做分类任务,方法二,不放过SAM强大特征提取能力,将SAM提取到的ImageEmbedding插入到其他cnn网络中

直接黏贴复制就好'''该类定义了VGG-16的基本结构。features: 代表VGG网络的主体部分,即所有的卷积层和池化层。avgpool: 是自适应平均池化层,将特征图大小调整为7x7。classifier: 是VGG网络的分类部分,由全连接层组成。_initialize_weights(): 初始化权重的方法。

cvxiayixiao的博客 3561
上一篇: C++实现二叉树所有操作 -- 创建递归遍历迭代遍历拷贝清空查找
下一篇: C++森林转化为二叉树代码
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值