__2.2 线索二叉树的线索化及遍历

#include "pch.h"
#include <iostream>

typedef char TElemType;
typedef enum {Link, Thread} PointerTag;  //Link=0表示指向左右孩子的指针
										 //Thread=1表示指向前去或后继的线索
typedef struct BiThrNode {
public:
	BiThrNode(TElemType dt) : data(dt) { }
	TElemType data;
	struct BiThrNode *lchild, *rchild;
	PointerTag LTag;   //左标志
	PointerTag RTag;   //右标志
} BiThrNode, *BiThrTree;

//先序创建线索二叉树
void CreateBiThrTree(BiThrTree& T) {
	TElemType ch;
	std::cin >> ch;
	if (ch == '#')
		T = nullptr;
	else {
		T = new BiThrNode(ch);
		if (!T)
			exit(OVERFLOW);
		CreateBiThrTree(T->lchild);
		CreateBiThrTree(T->rchild);
	}
}

//递归的中序遍历线索化
BiThrTree pre = nullptr;	//全局变量,始终指向刚刚访问过的节点
void InThreading(BiThrTree& T) {
	if (T) {
		InThreading(T->lchild);		//递归左子树线索化
		if (!T->lchild) {           //没有左子树
			T->LTag = Thread;		//前驱线索
			T->lchild = pre;		//左子树指向前驱节点
		}
		else
			T->LTag = Link;
		if (pre) {
			if (!pre->rchild) {	//前驱没有右孩子
				pre->RTag = Thread;		//后继线索
				pre->rchild = T;		//前驱右孩子指向后继(当前节点T)
			}
			else
				pre->RTag = Link;
		}
		pre = T;					//保持pre指向T的前驱
		InThreading(T->rchild);		//递归右子树线索化
	}
}

//添加头结点
BiThrTree addHead(BiThrTree& T) {
	BiThrNode *head = new BiThrNode('\0');
	head->LTag = Link;    //左孩子指向指针
	head->RTag = Thread;  //右孩子指向线索
	head->lchild = T;     //头结点的lchild指向二叉树的根节点

	while (T->lchild)   //找到最左的节点(中序遍历的第一个节点)
		T = T->lchild;
	T->LTag = Thread;   //使左标志为线索
	T->lchild = head;   //使最左节点的前驱指向头结点

	T = head->lchild;
	while (T->rchild)  //找到最右的节点(中序遍历的最后一个节点)
		T = T->rchild;
	T->RTag = Thread;
	T->rchild = head;  //最后一个节点的右线索指向头结点
	head->rchild = T;  //头结点的右线索指向最后一个节点
	return head;
}

//中序遍历二叉链表表示的线索二叉树
void InOrderTraverse_Thr(const BiThrTree& head) {
	BiThrTree p;
	p = head->lchild;
	while (p != head) {
		while (p->LTag == Link)
			p = p->lchild;
		std::cout << p->data << " ";
		while (p->RTag == Thread && p->rchild != head) {
			p = p->rchild;
			std::cout << p->data << " ";
		}
		p = p->rchild;
	}
}

int main() {
	BiThrTree BTree;
	std::cout << "请以先序输入二叉树:";
	CreateBiThrTree(BTree);		  //创建二叉树
	InThreading(BTree);			  //二叉树的中序递归线索化
	BTree = addHead(BTree); 	  //添加头结点
	std::cout << "\n中序遍历线索二叉树结果:";
	InOrderTraverse_Thr(BTree);   //中序遍历线索二叉树
	std::cout << "\n\n";

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40843865/article/details/89221697