二叉树线索化

该文详细介绍了如何对二叉树进行中序、逆向、先序和后序的线索化处理,以便于高效地进行遍历。通过在节点中添加额外的ltag和rtag标志以及线索指针,实现了在非递归情况下也能方便地访问树的各个节点。同时,提供了相应的遍历函数,如firstNode、nextNode等,用于按顺序访问线索化后的树节点。
摘要由CSDN通过智能技术生成
中序线索化
class TreeNode{
public:
	TreeNode * left,*right;
	int ltag,rtag;
	int data;
	TreeNode(int data): left(nullptr),right(nullptr),ltag(0),rtag(0),data(_data){}
};
class process{
public:
	TreeNode *pre = nullptr;
	void creatTree(TreeNode * root){
		if(root){
			inTread(root);
			if(pre -> right == nullptr){
				pre -> rtag = 1;
			}
		}
	}
	void inTread(TreeNode *root){
		if(!root){
			return;
		}
		inTread(root -> left);
		visit(root);
		inTread(root -> right);
	}
	void visit(TreeNode *root){
		if(root -> left == nullptr){
			root -> left = pre;
			root -> ltag = 1;
		}
		if(!pre && pre -> right == nullptr){
			pre -> right = root;
			pre -> rtag = 1;
		}
		pre = root;
	}
}

遍历

TreeNode * firstNode(TreeNode * root){
	if(root -> ltag == 0){
		root = root -> left;
	}
	return root;
}
TreeNode * nextNode(TreeNode *root){
	if(root -> rtag == 0){
		return firstNode(root -> right);
	}
	return root -> right;
}
void Inorder(TreeNode *root){
	while(TreeNode * p = firstNode(root); !p;p = nextNode(p)){
		visit(p);
	}
}
void visit(TreeNode * p){
	printf("%d ",p->data);
}

逆向遍历

TreeNode * lastNode(TreeNode * root){
	if(root -> rtag == 0){
		root = root -> right;
	}
	return root;
}
TreeNode * preNode(TreeNode *root){
	if(root -> ltag == 0){
		return lastNode(root -> left);
	}
	return root -> left;
}
void Inorder(TreeNode *root){
	while(TreeNode * p = lastNode(root); !p;p = preNode(p)){
		visit(p);
	}
}
void visit(TreeNode * p){
	printf("%d ",p->data);
}
先序线索化

注意防止转圈

class TreeNode{
public:
	TreeNode * left,*right;
	int ltag,rtag;
	int data;
	TreeNode(int data): left(nullptr),right(nullptr),ltag(0),rtag(0),data(_data){}
};
class process{
public:
	TreeNode *pre = nullptr;
	void creatTree(TreeNode * root){
		if(root){
			inTread(root);
			if(pre -> right == nullptr){
				pre -> rtag = 1;
			}
		}
	}
	void inTread(TreeNode *root){
		if(!root){
			return;
		}
		visit(root);
		if(root -> ltag == 0){
			inTread(root -> left);	
		}
		inTread(root -> right);
	}
	void visit(TreeNode *root){
		if(root -> left == nullptr){
			root -> left = pre;
			root -> ltag = 1;
		}
		if(!pre && pre -> right == nullptr){
			pre -> right = root;
			pre -> rtag = 1;
		}
		pre = root;
	}
}

遍历

void Inorder(TreeNode * root){
	while(root){
		visit(root);
		if(root -> rtag == 1){
			root = root -> right;
		}else{
			if(root -> ltag == 0){
				root  = root -> left;
			}else{
				root = root -> right;
			}
		}
	}
}
void visit(TreeNode *root){
	printf("%d ", root -> data);
}

先序线索化不能找到前驱节点

后序线索化
class TreeNode{
public:
	TreeNode * left,*right;
	int ltag,rtag;
	int data;
	TreeNode(int data): left(nullptr),right(nullptr),ltag(0),rtag(0),data(_data){}
};
class process{
public:
	TreeNode *pre = nullptr;
	void creatTree(TreeNode * root){
		if(root){
			inTread(root);
			if(pre -> right == nullptr){
				pre -> rtag = 1;
			}
		}
	}
	void inTread(TreeNode *root){
		if(!root){
			return;
		}
		inTread(root -> left);	
		inTread(root -> right);
		visit(root);
	}
	void visit(TreeNode *root){
		if(root -> left == nullptr){
			root -> left = pre;
			root -> ltag = 1;
		}
		if(!pre && pre -> right == nullptr){
			pre -> right = root;
			pre -> rtag = 1;
		}
		pre = root;
	}
}

后序线索化不能找到后继节点
逆后续遍历

void inorder(TreeNode * root){
	while(root){
		visit(root);
		if(root -> ltag = 1){
			root = root -> left;
		}else{
			if(root -> rtag == 0){
				root = root -> right;
			}else{
				root = root -> left;
			}
		}
	}
}
void visit(TreeNode *root){
	printf("%d ", root -> data);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值