线索二叉树的结构实现
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct ThreadBinaryTree
{
char data;
struct ThreadBinaryTree* leftChild;
struct ThreadBinaryTree* rightChild;
bool LTag=0; //左标记位
bool RTag=0; //右标记位
//都设置为0是因为bool类型默认初始化为1,下面程序中只是可以
//将标志位改成1,没有改成0的功能,所以都默认初始化为0避免出错
//标记位是0表示指向左右孩子的指针
//标记位是1表示指向前驱或后继的线索
};
ThreadBinaryTree* creatTree(ThreadBinaryTree* root, string s, int& index)
{
if (s[index] == '#')
return NULL;
else
{
root = new ThreadBinaryTree;
root->data = s[index];
root->leftChild = creatTree(root->leftChild, s, ++index);
root->rightChild = creatTree(root->rightChild, s, ++index);
}
return root;
}
void preTraverse(ThreadBinaryTree* root)
{
if (root == NULL)
return;
cout << root->data << endl;
preTraverse(root->leftChild);
preTraverse(root->rightChild);
}
ThreadBinaryTree* preNode; //设置全局变量,指向刚刚访问过的节点 全局变量默认初始化为NULL
//中序遍历线索化
void InThreading(ThreadBinaryTree* node)
{
if (node)
{
InThreading(node->leftChild);
//前驱节点线索化
if (!node->leftChild) //判断是否有左孩子,没有左孩子则执行
{
node->LTag = 1; //没有孩子标记位置1
node->leftChild = preNode; //左孩子指针指向前驱
}
//后继节点线索化
if (preNode != NULL) //为了避免preNode初始值是NULL而编译出错
{
if (!preNode->rightChild) //如果前驱没有右孩子 执行
{
preNode->RTag = 1;
preNode->rightChild = node; //前驱右孩子指针指向后继(当前节点node)
}
}
preNode = node; //将preNode按照遍历顺序走一步 保持preNode为当前节点的前驱
if (node->rightChild == NULL) //此处判断是为了在G位置可以将标志位改成1,不然直接返回没有改的机会
node->RTag = 1;
InThreading(node->rightChild);
}
}
#if 0
对某个节点进行后继节点线索化,会麻烦一些,因为此时node节点的后继还没有访问到
线索化的顺序是先对当前节点的左指针做前驱节点线索化,但要对当前节点的右指针做后继节点线索化时,
只有进入遍历中的下一个节点才能线索化上个节点的后继,因为是在中序遍历的情况下进行,所以遍历顺序是左->根->右,
因此只能对它的前驱节点preNode的右指针rightChild做判断,如果前驱没有右孩子,则前驱节点的后继就会指向当前节点
#endif
int _tmain(int argc, _TCHAR* argv[])
{
string s = "ABDH##I##EJ###CF##G##";
ThreadBinaryTree* root = NULL;
int index = 0;
root = creatTree(root, s, index);
preTraverse(root);
cout << "----------" << endl;
InThreading(root);
//检测I的后继是不是B
cout << root->leftChild->leftChild->rightChild->rightChild->data << endl;
//检测H的后继是不是D
cout << root->leftChild->leftChild->leftChild->rightChild->data << endl;
return 0;
}
图片: