构造中序线索二叉树

主要是利用二叉树的空指针域,若为空,使左指针指向前驱,并标记ltag为1;使右指针指向后驱,并标记rtag为1;

要注意的是构造结束后,此时pre指向最后一个结点,此时需记得pre->right = nullptr, pre->rtag = 1。否则这棵树的右子树无法遍历;

这样使得这些指针域不至于浪费,并能够加快查找结点前驱和后继的速度。

#include <iostream>
#include <string>
using namespace std;

typedef int ElementType;
typedef struct TreeNode{
	ElementType val;
	TreeNode* left;
	TreeNode* right;
	int ltag;
	int rtag;
	TreeNode(ElementType x):val(x), left(nullptr), right(nullptr)
		, ltag(0), rtag(0){}			
}*ThreadTree;

void visit(TreeNode* node)
{
	cout << node->val << " ";
}

void inOrder(ThreadTree root)
{
	if( root ){
		inOrder(root->left);
		visit(root);
		inOrder(root->right);
	}
}

ThreadTree BST_Insert(ThreadTree root, int n = 0)
{
	cout << "Please input " << n << " value to insert BST:\n";
	while( n-- )
	{
		ElementType x;
		cin >> x;
		ThreadTree t = new TreeNode(x);
		if( root == nullptr ){
			root = t;
			continue;
		}

		ThreadTree p = root, pre;
		while( p ){
			pre = p;
			if( x < p->val )
				p = p->left;
			else
				p = p->right;
		}
		if( x < pre->val ) pre->left = t;
		else pre->right = t;
	}
	return root;	
}

//	构造中序线索二叉树,注意参数是引用 
void InThread(ThreadTree& p, ThreadTree& pre)
{
	if( p ){
		InThread(p->left, pre);		//左子树线索化 
		if( !p->left ){				//左结点为空,指向前驱 
			p->left = pre;
			p->ltag = 1;
		}
		if( pre && !pre->right ){	//右节点为空,指向后继 
			pre->right = p;
			pre->rtag  = 1;
		}
		pre = p;					//当前结点转为前驱 
		InThread(p->right, pre);	//右子树线索化 
	}				
}  

bool createInThread(ThreadTree root)
{
	ThreadTree pre = nullptr;
	if( root ){
		InThread(root, pre);
		pre->right = nullptr;		//最后一个结点,没有后继 
		pre->rtag = 1;
		return true;
	}
	return false;
}

//	中序遍历第一个节点,是最左下的结点(不一定是叶节点) 
TreeNode* firstNode(ThreadTree p)
{
	while( p->ltag == 0 )
		p = p->left;
	return p;
}

//	后继结点,若无直接后继,则返回线索后继 
TreeNode* nextNode(ThreadTree p)
{
	if( p->rtag == 0 )
		return firstNode(p->right);
	else
		return p->right;	
}

void Thread_inOrder(ThreadTree root)
{
	for(TreeNode* p = firstNode(root); p; p = nextNode(p))
		visit(p);
	cout << "\n";	
}

//7
//6 2 8 1 4 7 3

int main( )
{
	int n;
	cin >> n;
	
	ThreadTree root = nullptr;
	root = BST_Insert(root, n);
	inOrder(root);
	
	if( createInThread(root) ){
                cout << "\n";
		Thread_inOrder(root);	
	}
	
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值