线索二叉树(图解+完整代码)

这篇具有很好参考价值的文章主要介绍了线索二叉树(图解+完整代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

⚽1.问题

🏐2.线索化

🏀 3.线索化带来的问题与解决

🥎4.完整代码


⚽1.问题

我们的二叉树学到现在,会产生两个问题:

  • 在n个结点的二叉树中,必定有n+1个空链域(叶子结点的左右子树空间浪费了)
  • 二叉树的遍历,无论是递归还是非递归算法,效率都不算高。

那我们能不能利用原本浪费掉的空间,来解决第二个问题呢?

倘若对下图二叉树进行中序遍历,可以得到1、3、6、8、10,我们可以知道3的前驱结点为1,后驱结点为6。但是,这种关系的建立是在完成遍历后得到的,那么,可不可以在建立二叉树的同时记录下前驱后继的关系,这样我们在寻找前驱后继结点时的效率将会大大提升!

线索二叉树(图解+完整代码)

我们的前辈们给出了答案:线索化 

🏐2.线索化

现将某结点的空指针域指向该结点的前驱后继,定义规则如下:

  • 若结点的左子树为空,则该结点的左孩子指针指向其前驱结点
  • 若结点的右子树为空,则该结点的右孩子指针指向其后继结点

这种指向前驱和后继的指针称为线索,将一棵普通的二叉树以某种次序遍历,并添加线索的过程称为线索化。

线索二叉树(图解+完整代码)

🏀 3.线索化带来的问题与解决

此时新的问题又产生了:我们如何区分一个lchild指针是指向左孩子还是前驱结点呢?

为了解决这个问题,我们需要添加标志位ltag和rtag,并定义以下规则

  • ltag==0,指向左孩子;ltag==1,指向前驱结点
  • rtag==0,指向右孩子;rtag==1,指向后继结点

线索二叉树(图解+完整代码)

🥎4.完整代码

中序线索化

void inOrderThreadTree(Node* node)
{
	//如果当前结点为NULL 直接返回
	if (node == NULL) {
		return;
	}
	//先处理左子树
	inOrderThreadTree(node->left_node);
	if (node->left_node == NULL)
	{
		//设置前驱结点
		node->left_type = 1;
		node->left_node = pre;
	}
	//如果结点的右子节点为NULL 处理前驱的右指针
	if (pre !=NULL && pre->right_node == NULL)
	{
		//设置后继
		pre->right_node = node;
		pre->right_type = 1;
	}
	//每处理一个节点 当前结点是下一个节点的前驱
	pre = node;
	//最后处理右子树
	inOrderThreadTree(node->right_node);
}

遍历

void inOrderTraverse(Node* root)
{
	//从根节点开始先找到最左边
	if (root == NULL)
	{
		return;
	}
	Node* temp = root;
	//先找到最左边结点 然后根据线索化直接向右遍历
	while (temp != NULL && temp->left_type == 0)
	{
		temp = temp->left_node;
	}
	while (temp != NULL)
	{
		//输出
		temp = temp->right_node;
	}
}

完整代码文章来源地址https://www.toymoban.com/news/detail-436198.html

#include<stdio.h>
#include<stdlib.h>
typedef struct Thread {
	struct Thread* left_node, *right_node;//左右指针
	int data;//需要存放的数据
	/*默认0代表左右孩子 1代表前驱或者后继*/
	int left_type;//类型标志
	int right_type;//类型标志
}Node;

Node* pre;//前驱结点的变量
Node* head;//头指针 指向某种遍历的第一个结点

void inOrderThreadTree(Node* node)
{
	//如果当前结点为NULL 直接返回
	if (node == NULL) {
		return;
	}
	//先处理左子树
	inOrderThreadTree(node->left_node);
	if (node->left_node == NULL)
	{
		//设置前驱结点
		node->left_type = 1;
		node->left_node = pre;
	}
	//如果结点的右子节点为NULL 处理前驱的右指针
	if (pre !=NULL && pre->right_node == NULL)
	{
		//设置后继
		pre->right_node = node;
		pre->right_type = 1;
	}
	//每处理一个节点 当前结点是下一个节点的前驱
	pre = node;
	//最后处理右子树
	inOrderThreadTree(node->right_node);
}

void inOrderTraverse(Node* root)
{
	//从根节点开始先找到最左边
	if (root == NULL)
	{
		return;
	}
	Node* temp = root;
	//先找到最左边结点 然后根据线索化直接向右遍历
	while (temp != NULL && temp->left_type == 0)
	{
		temp = temp->left_node;
	}
	while (temp != NULL)
	{
		//输出
		temp = temp->right_node;
	}

}

到了这里,关于线索二叉树(图解+完整代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 线索二叉树的画法

    视频讲解线索二叉树的画法(通俗易懂) 在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。 线索二叉树中的线索能记录每个结点前驱和后继信息

    2024年02月11日
    浏览(36)
  • 数据结构之线索二叉树

      数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用

    2024年01月23日
    浏览(39)
  • 【考研复习】二叉树的特殊存储|三叉链表存储二叉树、一维数组存储二叉树、线索二叉树

    三叉链表结构体表示如下图所示: 构造三叉链表方式: 另外设计一个填充函数,函数功能是将所有结点的parent结点填充正确。 线索二叉的的基本结构: 使用中序遍历的顺序进行线索化。代码中有一个难以理解的点,为什么不用p直接找后继,而是使用了前驱结点找后继。实

    2024年02月04日
    浏览(37)
  • 二叉排序树(二叉查找树、二叉搜索树)(图解+完整代码)

    目录 ⚽1.什么是二叉排序树 🏐2.构建二叉排序树 🏀3.二叉排序树的查找操作 🥎4.二叉排序树的删除 🎱5.完整代码 我们直接看它的性质: 若它的左子树不空,则左子树上所有结点的值均小于它根结点的值。 若它的右子树不空,则右子树上所有结点的值均大于它根结点的值。

    2024年02月03日
    浏览(33)
  • 数据结构--线索二叉树的概念

    中序遍历序列:D G B E A F C ①如何找到指定结点p在中序遍历序列中的前驱? ②如何找到p的中序后继? 思路: 从根节点出发,重新进行一次中序遍历,指针q记录当前访问的结点,指针pre记录上一个被访问的结点 ①当q p时,pre为前驱 ②当pre p时,q为后继 缺点 : 找前驱、后继很不方便

    2024年02月13日
    浏览(47)
  • 数据结构--线索二叉树找前驱后继

    在中序线索二叉树中找到指定结点*p的 中序后继 color{red}中序后继 中序后继 next ①若p-rtag == 1,则next = p-rchild ②若p-rtag== 0 中序遍历――左根右 左根(左根右) 左根((左根右)根右) next = p的右子树中最左下结点 在中序线索二叉树中找到指定结点*p的 中序前驱 color{red}中序前驱

    2024年02月12日
    浏览(41)
  • 数据结构--树4.2.3(线索二叉树)

    利用中序遍历可以解决二叉树中空出来的内存,以及前驱后继的问题。 lchild ltag data rtag rchild ——ltag为0时指向该结点的左孩子,为1时指向该结点的前驱。 ——rtag为0时指向该结点的有孩子,为1时指向该结点的后继。

    2024年02月11日
    浏览(34)
  • 数据结构之线索二叉树详细解释

    1.1 线索二叉树的原理 我们现在倡导节约型社会,一切都应该以节约为本。但当我们创建二叉树时我们会发现其中一共有两个指针域,有的指针域指向的结构为空,这也就浪费了很多空间。所以为了不去浪费这些空间我们采取了一个措施。就是利用那些空地址,存放指向结点

    2023年04月20日
    浏览(40)
  • 数据结构——二叉树线索化遍历(前中后序遍历)

    为什么要转换为线索化         二叉树线索化是一种将普通二叉树转换为具有特殊线索(指向前驱和后继节点)的二叉树的过程。这种线索化的目的是为了提高对二叉树的遍历效率,特别是在不使用递归或栈的情况下进行遍历。         将二叉树线索化的主要目的是为了

    2024年02月09日
    浏览(38)
  • 数据结构三叉链表与线索二叉树的思路与实现详解

    ❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 我们知道最常见的链式存储二叉树的结构体中有数据域、左孩子指针以及右孩子指针,通过递归来创建二叉树。显而易见的是,想找到二叉树中任意一个结点的 前驱 或 后

    2024年02月02日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包