线索二叉树的概念,线索化,找前驱,后继结点的C语言代码实现

本文介绍了线索二叉树的概念,通过利用二叉树链式存储的空指针,增加线索指向前驱和后继结点,提高了空间利用率。详细讲解了中序、先序和后序线索二叉树的线索化过程,并提供了C语言代码实现,包括线索二叉树的结点结构、线索化代码和测试案例。
摘要由CSDN通过智能技术生成

1. 线索二叉树

1.1 线索二叉树的概念

线索二叉树的概念是基于二叉树的链式存储的;
在传统的二叉链表存储中,仅能体现一种父子关系,不能直接得到各个结点在遍历中的前驱和后继;
同时在链式存储中,每个叶节点都有2个空指针,所以我们设想能否利用这些空指针来存放指向其前驱或后继结点。
这样不仅能提高存储空间的利用效率,同时还可以在遍历中方便的查找前驱和后继结点。

1.2 线索二叉树的结点结构

二叉树结点结构

// 线索二叉树结点
typedef struct ThreadNode
{
   
	ElemType data;
	struct ThreadNode *lchild, *rchild;
	// 相比普通的二叉树只多了这2个变量
	// 左,右线索标志;用来表明该结点的左,右指针指向的是线索还是孩子结点
	int ltag, rtag;		
}ThreadNode, *ThreadTree;

1.3 三种线索二叉树的线索化示意图

(1)中序线索二叉树

线索指向中序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的中序遍历(左根右)为:D G B E A F C

  • 前驱线索,由左孩子指针充当,是黄色虚线
  • 后继线索,由右孩子指针充当,是紫色虚线
    中序线索二叉树

详细图示(红色数字表示的是“中序遍历”的序列):
在这里插入图片描述

(2)先序线索二叉树

线索指向先序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的先序遍历(根左右)为:A B D G E C F
在这里插入图片描述
详细图示:
在这里插入图片描述

(3)后续线索二叉树

线索指向后序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的后序遍历(左右根)为:G D E B F C A
在这里插入图片描述
详细图示:
在这里插入图片描述

2. 二叉树的线索化(C语言代码实现)

二叉树线索化的核心就是对中序/先序/后序遍历算法(递归实现)进行改造用一个指针 pre 记录当前访问结点的前驱结点,在具体访问一个结点时,连接该结点与该结点的前驱结点的线索信息。

2.1 线索二叉树的结点结构定义

#include <stdio.h>
#include <stdlib.h>

#define MaxSize 100

struct ElemType
{
   
	int value;
};

// 线索二叉树结点
typedef struct ThreadNode
{
   
	ElemType data;
	struct ThreadNode *lchild, *rchild;
	// 相比普通的二叉树只多了这2个变量
	// 左,右线索标志;用来表明该结点的左,右指针指向的是线索还是孩子结点
	int ltag, rtag;		
}ThreadNode, *ThreadTree;

// 定义一个全局变量 pre,指向当前访问节点的前驱
ThreadNode *pre = NULL;

2.2 线索化公共部分代码

前面已经介绍过,主要修改的是访问结点的那部分代码。
(1)图示(中序线索化
q 指针,指向当前遍历的结点;pre 指针,指向当前遍历结点的前一个结点。
在这里插入图片描述

特别注意

  • 建立前驱线索(黄色虚线)时,一定是 pre 指针指向黄色虚线箭头的末尾结点,q 指针指向黄色虚线箭头的开始结点。
    在这里插入图片描述
  • 建立后继线索(紫色虚线)时,一定是pre指针指向紫色虚线的开头结点,q指针指向紫色虚线的末尾结点

在这里插入图片描述

(2)代码

// 访问某个节点
void visit
  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于中序线索化二叉树的代码实现: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树结点 typedef struct TreeNode { char data; struct TreeNode *left; struct TreeNode *right; int ltag, rtag; // 线索化标志,0表示指向左右子树,1表示指向前驱后继结点 } TreeNode; // 创建二叉树 TreeNode* createTree() { char ch; scanf("%c", &ch); if (ch == '#') { return NULL; } TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = ch; node->left = createTree(); node->right = createTree(); node->ltag = 0; node->rtag = 0; return node; } // 中序线索化 void inOrderThreading(TreeNode *root, TreeNode **pre) { if (root) { inOrderThreading(root->left, pre); if (!root->left) { root->ltag = 1; root->left = *pre; } if (*pre && !(*pre)->right) { (*pre)->rtag = 1; (*pre)->right = root; } *pre = root; inOrderThreading(root->right, pre); } } // 查结点后继结点 TreeNode* findNextNode(TreeNode *node) { if (node->rtag == 1) { return node->right; } else { TreeNode *p = node->right; while (p && p->ltag == 0) { p = p->left; } return p; } } int main() { TreeNode *root = createTree(); TreeNode *pre = NULL; inOrderThreading(root, &pre); printf("请输入要查后继结点结点值:"); char ch; scanf("%c", &ch); TreeNode *node = root; while (node && node->data != ch) { node = node->right; } if (!node) { printf("未到该结点!\n"); } else { TreeNode *nextNode = findNextNode(node); if (nextNode) { printf("该结点后继结点为:%c\n", nextNode->data); } else { printf("该结点没有后继结点!\n"); } } return 0; } ``` 该程序中,`createTree()`函数用于创建二叉树,`inOrderThreading()`函数用于中序线索化二叉树,`findNextNode()`函数用于查结点后继结点。在 `main()` 函数中,先输入要查后继结点结点值,然后查结点并调用 `findNextNode()` 函数查后继结点,最后输出结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值