线索二叉树的搭建和遍历(c++版)

  • 线索二叉树的搭建和遍历(c++版)

动画版 https://www.bilibili.com/video/BV1MP4y1i7mK/

#include <iostream>
using namespace std;
#define TRUE 1
#define FALSE 0

class ClueBinaryTree
{
private:
	typedef struct node
	{
		char data;					// 数据域
		node* lchild, * rchild;		// 左孩子、右孩子
		bool ltag, rtag;			// 左标识、右标识(0代表指向左右孩子,1代表指向前驱后继)
	}BNode, * BTree;

	string str;						// 输入的字符串
	int sub;						// 字符串下标
	BTree Root;						// 根节点
	BTree Head;						// 头节点
	BTree Last;						// 始终指向刚刚访问过的节点

public:
	ClueBinaryTree()
	{
		this->str = "ABD  E  CF  G  ";
		this->sub = 0;
		this->Root = NULL;
		this->Head = NULL;
		this->createTree(this->Root);					// 初始化二叉树
		this->InOrderThreading(this->Head, this->Root);	// 中序遍历线索化
		this->InOrderTraverse(this->Head);				// 中序遍历输出二叉树
	}
	// 初始化二叉树
	void createTree(BTree& elem)
	{
		char c = this->str[this->sub++];

		if (' ' == c)
		{
			elem = NULL;
		}
		else
		{
			elem = new BNode;
			elem->data = c;
			elem->ltag = FALSE;
			elem->rtag = FALSE;

			this->createTree(elem->lchild);
			this->createTree(elem->rchild);
		}
	}
	// 二叉树中序遍历线索化
	void InThreading(BTree& T)
	{
		if (T)
		{
			this->InThreading(T->lchild);	// 递归左孩子线索化

			// 节点处理
			// ------------------------------------------------------------------------------
			if (!T->lchild)					// 如果当前节点没有左孩子,左指针指向前驱(即上一个节点)
			{
				T->ltag = TRUE;
				T->lchild = this->Last;
			}
			if (!this->Last->rchild)			// 如果当前节点的上一个节点没有右孩子,右指针指向后继(即当前节点)
			{
				this->Last->rtag = TRUE;
				this->Last->rchild = T;
			}
			this->Last = T;					// 当前节点变成上一个节点,然后继续
			// ------------------------------------------------------------------------------

			this->InThreading(T->rchild);	// 递归右孩子线索化
		}
	}
	// 构建头节点(头节点,根节点)
	void InOrderThreading(BTree& Head, BTree& Root)
	{
		Head = new BNode;				// 创建头节点
		Head->ltag = FALSE;				// 设置左标识(左指针指向左孩子)
		Head->rtag = TRUE;				// 设置右标识(右指针指向后继)
		Head->rchild = Head;			// 后继为自身
		if (!Root)						// 如果为空树,左孩子为自身
		{
			Head->lchild = Head;
		}
		else							// 不为空树
		{
			Head->lchild = Root;		// 头节点左孩子为根节点
			this->Last = Head;			// “上一个节点”最初形态

			this->InThreading(Root);	// 开始线索化

			this->Last->rchild = Head;	// “上一个节点”的右孩子为头结点
			this->Last->rtag = TRUE;	// “上一个节点”的右标识为指向后继
			Head->rchild = this->Last;	// 头节点的后继为“上一个节点”
		}
	}
	// 中序遍历二叉树,非递归
	void InOrderTraverse(BTree& Head)
	{
		BTree p;
		p = Head->lchild;

		cout << "中序遍历:";

		while (p != Head)
		{
			while (p->ltag == FALSE)
			{
				p = p->lchild;
			}
			cout << p->data << " ";

			while (p->rtag == TRUE && p->rchild != this->Head)
			{
				p = p->rchild;
				cout << p->data << " ";
			}

			p = p->rchild;
		}
		cout << endl;
	}
};

int main()
{
	ClueBinaryTree c;
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值