#include <iostream>
#include <stdlib.h>
using namespace std;
enum PointerTag {LINK , INDEX};
typedef char Elemtype;
typedef struct node {
Elemtype data;
struct node *lchild , *rchild;
PointerTag lTag , rTag;
} *ThreadTree;
//声明所需要用到的函数
void createTree(ThreadTree *);
void displayBefore(ThreadTree);
void displayBetween(ThreadTree);
void inorderThrTree(ThreadTree * , ThreadTree);
void inorderThread(ThreadTree);
void displayThreadTree(ThreadTree);
//用于线索化的时候,记录前一个结点
ThreadTree pre;
int main()
{
ThreadTree tree;
createTree(&tree);
cout << "先序显示未线索化的树:" << endl;
displayBefore(tree);
cout << endl;
cout << "中序显示未线索化的树:" << endl;
displayBetween(tree);
ThreadTree newTree;
//线索化树
inorderThrTree(&newTree , tree);
cout << endl;
cout << "显示线索化后的树:" << endl;
displayThreadTree(newTree);
return 0;
}
//创建一棵树,当输入为空格的时候,其当前结点为NULL
void createTree(ThreadTree *tCurrTree) {
char cIn;
cin.get(cIn);
(*tCurrTree) = NULL;
if(cIn == '\0') {
return;
}
if(cIn != ' ') {
(*tCurrTree) = (ThreadTree)malloc(sizeof(node));
(*tCurrTree)->data = cIn;
createTree(&(*tCurrTree)->lchild);
createTree(&(*tCurrTree)->rchild);
}
}
//先序遍历树显示,用于证明树创建的正确性
void displayBefore(ThreadTree tCurrTree) {
if(tCurrTree != NULL) {
cout << tCurrTree->data << " ";
displayBefore(tCurrTree->lchild);
displayBefore(tCurrTree->rchild);
}
}
//中序遍历树显示,用于证明树创建的正确性
void displayBetween(ThreadTree tCurrTree) {
if(tCurrTree != NULL) {
displayBefore(tCurrTree->lchild);
cout << tCurrTree->data << " ";
displayBefore(tCurrTree->rchild);
}
}
//用已有的树创建一个带头结点的线索树
void inorderThrTree(ThreadTree *root , ThreadTree tree) {
//创建线索树头结点
(*root) = (ThreadTree)malloc(sizeof(node));
if(!(*root)) {
exit(0);
}
//让头结点的左子树为线索,用于让线索化后最后一个结点的右子树指向它
(*root)->rTag = LINK;
(*root)->lTag = INDEX;
(*root)->lchild = (*root);
if(!tree) {
(*root)->rchild = (*root);
} else {
(*root)->rchild = tree;
pre = (*root);
inorderThread(tree);
pre->rchild = (*root);
pre->rTag = INDEX;
(*root)->lchild = pre;
}
}
//对一个无头指针的树进行线索化
void inorderThread(ThreadTree tCurrTree) {
if(tCurrTree != NULL) {
//线索化当前结点的左子树
inorderThread(tCurrTree->lchild);
//线索化当前结点,由于其下一个结点不知道
//所以它的右孩子指针留给它的下一个结点进行线索化
if(tCurrTree->lchild == NULL) {
tCurrTree->lTag = INDEX;
tCurrTree->lchild = pre;
}
if(pre->rchild == NULL) {
pre->rTag = INDEX;
pre->rchild = tCurrTree;
}
pre = tCurrTree;
//线索化当前结点的右子树
inorderThread(tCurrTree->rchild);
}
}
//显示线索化后的树,由于树是中序线索化,所以显示的结果与中序遍历的结果一样
void displayThreadTree(ThreadTree tree) {
ThreadTree head = tree->rchild;
while(head != tree) {
//移动到第一个结点并打印值,即最左下的结点
while(head->lTag == LINK) {
head = head->lchild;
}
cout << head->data << " ";
//判断其右孩子指针是否是线索,如果是直接下移并输出
//如果不是,移动到它的右子树,进行新一轮的遍历
if(head->rTag == INDEX && head->rchild != tree) {
head = head->rchild;
cout << head->data << " ";
}
head = head->rchild;
}
}
分享到:
相关推荐
/* 按先序输入二叉线索树中结点的值,构造二叉线索树T */ /* 0(整型)/空格(字符型)表示空结点 */ Status InOrderThreading(BiThrTree *Thrt,BiThrTree T) { /* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点...
3. **转化过程**:将二叉树转化为前序线索树通常包括以下步骤: - 初始化:首先,为每个节点的左、右指针添加线索标志位,表示该指针是否为空。 - 遍历:从根节点开始,对每个节点进行处理。如果节点的左子节点为...
数据结构作业的二叉线索树,实现 1.建立一个二叉树并且先序线索化二叉树并且先序遍历线索二叉树 2.建立一个二叉树并且先序线索化二叉树并且中序遍历线索二叉树 3.建立一个二叉树并且先序线索化二叉树并且后序遍历...
线索二叉树是一种在二叉树中添加线索(thread)以方便进行前序...它使用非递归的方式,通过线索指针优化了遍历效率,并且可能包含了对树的可视化功能。这样的实现对于理解和掌握数据结构中的线索二叉树概念非常有帮助。
线索树,又称线索二叉树,是二叉树数据结构的一种扩展形式,它在二叉链表的基础上增加了一些额外的线索来辅助查找操作。在普通的二叉链表中,我们通常只能通过指针找到左右子节点,但在线索树中,我们还可以通过线索...
数据结构中的线索树是一种特殊的二叉树存储结构,它的设计目的是为了方便在非递归方式下进行树的遍历,特别是对于中序遍历。在传统的二叉链表中,每个结点仅包含左右孩子指针,而在线索树中,我们额外添加了两个标志...
二叉树的创建、遍历、以及左右子树交换,非递归遍历,叶子节点计算及线索树等完整程序
"线索二叉树的建立、删除、插入、恢复线索" 线索二叉树是一种特殊的二叉树,它的每个结点都带有指向其前驱和后继结点的指针,这些指针称为线索。线索二叉树可以分为前序线索二叉树、中序线索二叉树和后序线索二叉树...
对于后序线索树和前序线索树,由于需要考虑双亲节点的信息,找到节点的后继或前驱可能较为复杂,需要使用包含指向双亲结点指针的三叉链表作为存储结构。 线索二叉树的主要优势在于它能够非递归地进行遍历,虽然时间...
然而,对于前序线索树和后序线索树,由于遍历规则的不同,查找前驱或后继可能需要知道节点的双亲信息,因此可能需要更复杂的存储结构,如带双亲指针的三叉链表。 线索二叉树的遍历算法,如中序遍历,可以通过非递归...
个人认为比较简洁 使用递归方式 创建使用扩展二叉树更加便捷 且有部分先序线索化代码 不够完善
`BiThrTree`是`BiThrNode`类型的指针,用于表示二叉线索树。 接着,我们看到了`CreatBinTree`函数,用于根据先序序列创建二叉链表。这个函数通过递归的方式构造二叉树。先读取一个字符,如果是空格,则表示当前节点...
5. **查找直接前驱**:在后序线索树中,给定结点p,其直接前驱q是所有以p为右孩子的结点的最近公共祖先。 通过线索二叉树,我们可以高效地进行各种遍历操作,如中序遍历、前序遍历和后序遍历,而无需使用辅助数据...
线索二叉树
线索二叉树代码和讲解,内容详细全面,通俗易懂,通过测试,代码可以直接使用,方便大家学习.
- **前序线索树的遍历**:任何一棵二叉树都可以不用栈实现前序线索树的前序遍历,这是因为前序线索树通过调整结点间的链接实现了遍历过程中的自动回溯。 - **后序线索树的遍历**:并非所有二叉树的后序线索树进行...
(2)在中序线索二叉树类模板中增加函数成员 InsertLeftChild(p,e),实现在中序线索二 叉树指定结点 p 上插入左孩子结点 e。 (3)在中序线索二叉树类模板中增加函数成员 PostOrder(),实现不用栈后序遍历二叉 树。 ...
在本实验中,我们将深入探讨数据结构中的树概念,特别是二叉线索树和递归在二叉树操作中的应用。二叉线索树是一种特殊的二叉树,它通过添加线索(links)来帮助在非递归方式下进行遍历。线索二叉树的主要目标是优化...
中序线索化二叉树的非递归算法:设计技巧:依某种顺序遍历二叉树,对每个结点p,判断其左指针是否为空,以及其前驱结点pre的右指针是否为空。