中序线索化二叉树

6 篇文章 0 订阅
4 篇文章 0 订阅

注意两个规定:在遍历序里的第一个元素没有前驱,最后一个元素没有后继,但规定:让它们分别指向head节点,便于遍历操作

#include<bits/stdc++.h>
using namespace std; 
struct Bth_node {
	int val;
	int ltag;
	int rtag;
	Bth_node* left;
	Bth_node* right;
	Bth_node(int val = 0, Tnode* left = nullptr, Tnode* right = nullptr, int ltag = 0, int rtag = 0)
		:val(val), left(left), right(right),ltag(ltag),rtag(rtag) {};
};
struct Bth_Tree {
private:
	bool lflag;
public:
	Bth_node* root;
	Bth_node* head; //指向root节点 
	Bth_node* pre; //在线索化中始终可见的 前驱节点 
	Tree() {
		root = nullptr;
		lflag = true;
	}
	void createTree(string& s);
	void createThread(); //在这个函数里建head节点 
	void thread(Bth_node*&  r); //可不传递引用类型 
	void Bth_InOrder(); 
};

int main(){
	
	return 0;
}
//中序线索化二叉树  
void Bth_Tree::createThread(){
	head = new Bth_node(); //为 root 做 pre 节点 
	head->ltag = 0, head->rtag = 1; //head左孩子指向root,右节点为空 
	head->right = root; //线索化到root节点,实际可为任意节点。最终要线索化到 中序序列 的最后一个节点 
	if(root == nullptr){
		head->left = head; //建空树 
		head->right = nullptr; 
	}
	else{
		head->left = root; //将实际首节点作为左孩子
		pre = head; //pre始终指向节点r(thread函数的参数)的前驱节点,没有前驱则指向head 
		
		thread(root); //中序遍历线索化二叉树 所有节点 
		
		pre->rtag = 1; //给遍历序最后一个节点设置rtag right
		pre->right = root; 
		head->right = pre;  //最终对head的线索化,pre指向遍历序的最后节点 
	} 
	
}
void Bth_Tree::thread(Bth_node*& r){ // 对 r 为头节点的树 进行线索化 
	if(r != nullptr){ 
	
		Thread(r->left); //线索化左子树 
		if(r->left == nullptr){
			r->left = pre;  
			r->ltag = 1; 
		}
		//else r->ltag = 0; //应该可不用,默认为0 
		if(pre->right == nullptr){ //注意是 pre 节点 !!
			pre->right = r; //pre在 遍历序 是r的前驱,反过来r在遍历序就是pre的后继 
			pre->rtag = 1; 
		}
		//else r->rtag = 0;
		pre = r; // pre 始终在 遍历序 中追随者r节点,故容易为其他节点提供前驱 
		Thread(r->right); //线索化右子树 
			
	}
}
void Bth_Tree::Bth_InOrder(){
	Bth_node* p = head->left; //即 root 节点
	while(p != head){  //非空树 
		while(p != head && p->ltag == 0){ 
			p = p->left;
		}
		//对于子树,中序遍历 第一个节点 
		cout<<p->val<<" ";
		while(p->rtag == 1 && p->right != head){ //根据线索访问后继 第二个条件为了保证p不是最右节点 
			p = p->right; 
			cout<<p->val<<" ";
		}
		p = p->right; //不再是线索,访问其右节点 下一轮循环解决 
	}
}
void Bth_Tree::createTree(string& s) { //括号表示串 建树 
	stack<Bth_node*>st;
	Bth_node* p, q;  //p 指向当前节点, q 指向栈顶节点/曾经节点 
	bool lflag = false;
	int i = 0, n = s.size();
	while (i < n) {
		char ch = s[i];
		switch (ch) {
		case '(':
			st.push(p); //当前节点成为 曾经节点 
			lflag = true;
			break;
		case ')':
			st.pop(); //曾经节点 已处理完 
			break;
		case ',':
			lflag = false;  //区分左右孩子节点 
			break;
		default:
			//当前节点 
			int num = 0;
			while (i < n && s[i] >= '0' && s[i] <= '9') {
				num = num * 10 + s[i++] - '0';
			}
			i--;
			p = new Bth_node(num);
			if (root == nullptr) {
				root = p; //栈必然为空 
			}
			else {
				if (!st.empty()) { //栈的第一个节点  
					if (lflag) {
						st.top()->left = p;
					}
					else {
						st.top()->right = p;
					}
				}
			}
			break;
		}
		i++;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾影林深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值