线索二叉树的结构实现

线索二叉树的结构实现

#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;
}

图片:

猜你喜欢

转载自blog.csdn.net/SwordArcher/article/details/80005071