目录
1. 二叉线索树的节点结构体
typedef struct ClueBiTreeNode {//定义二叉线索树的节点结构体
char data;//数据域
ClueBiTreeNode* LeftChild;//左孩子
int LTag;
ClueBiTreeNode* RightChild;//右孩子
int RTag;
// LTag=0表示当前节点左指针域保存的是左孩子地址 1保存是当前节点的前驱节点线索
}*BiTreeClue;// BiTreeClue --》二叉线索树的结构体指针
2.按先序遍历的顺序创建二叉树
void CreateBiTree(BiTreeClue& T) {
char c;
cin >> c;//输入字符
if (c == '*') {
T = NULL;
}//孩子为空时,其值为‘*’
else {
T = new ClueBiTreeNode;//申请新节点,用来保存孩子节点
T->data = c;//为新节点填充数据
T->LTag = 0;//新节点初始化,存在左孩子
T->RTag = 0;//新节点初始化,存在右孩子
CreateBiTree(T->LeftChild);//递归处理左孩子
CreateBiTree(T->RightChild);//递归处理右孩子
}
}
3. 创建线索二叉树(使用先序/前序遍历线索化)
void CreateClueOrderBiTree(BiTreeClue& Phead, BiTreeClue& P) {
if (P == NULL) return;
if (P->LeftChild == NULL)
{
P->LeftChild = Ppre;
P->LTag = 1;
}
if (Ppre != NULL && Ppre->RightChild == NULL) {
Ppre->RightChild = P;
Ppre->RTag = 1;
}
Ppre = P;
if (P->LTag == 0) {
CreateClueOrderBiTree(Ppre,P->LeftChild);
}
if(P->RTag==0)
CreateClueOrderBiTree(Ppre, P->RightChild);
}
4.前序遍历打印前序线索二叉树
void OrderderPrint(const BiTreeClue P) {
ClueBiTreeNode* Q = P;//Q为根节点
while (Q)//Q存在时
{
while (Q->LTag==0)
{
cout << Q->data << " ";//打印出有左孩子的节点值
Q = Q->LeftChild;//向左移动
}
while (Q->RTag==1)
{
cout << Q->data << " ";//打印出最后一个左节点的右节点值
Q = Q->RightChild;//向这个节点的右子数移动
}
cout << Q->data << " ";//打印出这个右子数的值
if (Q->LTag == 0) //当它有左孩子时
Q = Q->LeftChild;//移动到它的左孩子上
else
Q = Q->RightChild;//移动到它的右孩子上
}
}
5.线索二叉树的节点数
int TreeNodeCount(BiTreeClue& T) {
if (T == NULL)
return 0;
else if (T->LTag == 1 && T->LTag == 1)
return 1;
else
return TreeNodeCount(T->LeftChild) + TreeNodeCount(T->LeftChild) + 1;
}
完整代码
#include <iostream>
using namespace std;
typedef struct ClueBiTreeNode {//定义二叉线索树的节点结构体
char data;//数据域
ClueBiTreeNode* LeftChild;//左孩子
int LTag;
ClueBiTreeNode* RightChild;//右孩子
int RTag;
// LTag=0表示当前节点左指针域保存的是左孩子地址 1保存是当前节点的前驱节点线索
}*BiTreeClue;// BiTreeClue --》二叉线索树的结构体指针
ClueBiTreeNode* Ppre;
//按先序遍历的顺序创建二叉树
void CreateBiTree(BiTreeClue& T) {
char c;
cin >> c;//输入字符
if (c == '*') {
T = NULL;
}//孩子为空时,其值为‘*’
else {
T = new ClueBiTreeNode;//申请新节点,用来保存孩子节点
T->data = c;//为新节点填充数据
T->LTag = 0;//新节点初始化,存在左孩子
T->RTag = 0;//新节点初始化,存在右孩子
CreateBiTree(T->LeftChild);//递归处理左孩子
CreateBiTree(T->RightChild);//递归处理右孩子
}
}
//求线索二叉树的节点数
int TreeNodeCount(BiTreeClue& T) {
if (T == NULL)
return 0;
else if (T->LTag == 1 && T->LTag == 1)
return 1;
else
return TreeNodeCount(T->LeftChild) + TreeNodeCount(T->LeftChild) + 1;
}
//先序遍历创建线索二叉树
void CreateClueOrderBiTree(BiTreeClue& Phead, BiTreeClue& P) {
if (P == NULL) return;
if (P->LeftChild == NULL)
{
P->LeftChild = Ppre;
P->LTag = 1;
}
if (Ppre != NULL && Ppre->RightChild == NULL) {
Ppre->RightChild = P;
Ppre->RTag = 1;
}
Ppre = P;
if (P->LTag == 0) {
CreateClueOrderBiTree(Ppre,P->LeftChild);
}
if(P->RTag==0)
CreateClueOrderBiTree(Ppre, P->RightChild);
}
//先序打印先序线索二叉树
void OrderderPrint(const BiTreeClue P) {
ClueBiTreeNode* Q = P;//Q为根节点
while (Q)//Q存在时
{
while (Q->LTag==0)
{
cout << Q->data << " ";//打印出有左孩子的节点值
Q = Q->LeftChild;//向左移动
}
while (Q->RTag==1)
{
cout << Q->data << " ";//打印出最后一个左节点的右节点值
Q = Q->RightChild;//向这个节点的右子数移动
}
cout << Q->data << " ";//打印出这个右子数的值
if (Q->LTag == 0) //当它有左孩子时
Q = Q->LeftChild;//移动到它的左孩子上
else
Q = Q->RightChild;//移动到它的右孩子上
}
}
int main() {
BiTreeClue P;
BiTreeClue Phead;
cout << "请按先序遍历的顺序创建二叉树,若其节点的左孩子或右孩子不存在则使用*代替!如:(ABD**E**CF**G**)" << endl;
CreateBiTree(P);
CreateClueOrderBiTree(Phead, P);
cout << "先序遍历的先序线索二叉树为:";
OrderderPrint(P);
cout << endl;
cout << "该先序线索二叉树的节点数为:" << TreeNodeCount(P);
cout << endl;
cout << endl;
system("pause");
}
运行结果及截图
下图为测试用例: (ABD**E**CF**G**)
前序遍历:A B D E C F G
中序遍历:D B E A F C G
后序遍历:D E B F G C A