树--线索二叉树的建立及其遍历

0线索二叉树的存储结构体:
在这里插入图片描述1先序序列化:
在这里插入图片描述
先序构树思想:
对于先序线索二叉树,我想提醒的是:每次只会把当前节点的左子树前驱链上,
这一次的 后继 不会在本次链上,当pCur指向下一个节点的时候,
才会把上一次的后继链上
代码:
先序线索化:

在这里插入图片描述
先序遍历的思想:
先往左遍历一遍,到底了之后往后继节点或者右子树找(要先判断是右子树还是线索节点)

#include<bits/stdc++.h>
using namespace std;
struct node{
	node * left;
	node * right;
	int ltag;
	int rtag;
	char data;
	node():left(NULL),right(NULL),ltag(0),rtag(0){
	}
};
typedef node * tree;
tree pre=new node;
void create(tree & root){
	char c;
	c=getchar();
	if(c=='#'){
		root =NULL;
		return ;
	}
	if(c=='\n')return;
	root=new node;//这一步一定不要漏了!!! 
	root->data=c;
	create(root->left);
	create(root->right);
}

//构建先序线索树 
void preOrderThreading(tree & node){
	if(!node)return;
	if(!node->left){
		node->left=pre;
		node->ltag=1; 
	}
	if(pre!=NULL&&!pre->right){
		pre->right=node;
		pre->rtag=1;
	}
	pre=node;
	if(node->left&&node->ltag==0)
	    preOrderThreading(node->left);
    if(node->right&&node->rtag==0)
	    preOrderThreading(node->right);
} 
//对于先序线索二叉树,我想提醒的是:每次只会把当前节点的左子树前驱链上,
//这一次的 后继 不会在本次链上,当pCur指向下一个节点的时候,
//才会把上一次的后继链上

//遍历先序线索树
void preOrder(tree node){
	if(node==NULL)return;
	tree temp=node;
	while(temp!=NULL){
		while(temp->left&&temp->ltag==0){
			cout<<temp->data<<" ";
			temp=temp->left;
		}
		cout<<temp->data<<" ";//还没有把最后一个输出 
		if(temp->rtag==1)temp=temp->right;//跳到后继节点上 
		while(temp!=NULL){
			if(temp->left&&temp->ltag==0)break;
			//如果有左子树,就break,以便重新遍历 
			cout<<temp->data<<" ";
			temp=temp->right;
		}
	}
} 
int main(){
	tree node;
	create(node);
	pre=node;
	preOrderThreading(node);
	preOrder(node); 
}

2中序线索化:
在这里插入图片描述
中序构树思想:
和先序差不多,所以先理解好先序,在看中序:
遍历:
先找到最左边的,然后找右子树或者后继线索节点

#include<bits/stdc++.h>
using namespace std;
struct node{
	node * left;
	node * right;
	int ltag;
	int rtag;
	char data;
	node():left(NULL),right(NULL),ltag(0),rtag(0){
	}
};
typedef node * tree;
tree pre=new node;
void create(tree & root){
	char c;
	c=getchar();
	if(c=='#'){
		root =NULL;
		return ;
	}
	if(c=='\n')return;
	root=new node;//这一步一定不要漏了!!! 
	root->data=c;
	create(root->left);
	create(root->right);
}
void inOrderThreading(tree node){
	if(!node)return;
	inOrderThreading(node->left);
	if(node->left==NULL){
		node->left=pre;
		node->ltag=1;
	}
	if(pre&&pre->right==NULL){
		pre->right=node;
		pre->rtag=1;
	}
	pre=node;
	inOrderThreading(node->right);
} 
//首先按照中序遍历的顺序,找到二叉树的最左边的节点,
//判断是否有前驱,有则遍历访问,没有则看右子树和后继的情况。  
void inOrder(tree node){
	if(!node)return;
	tree root =node;
	while(root){
		while(root->left&&root->ltag==0){
			root=root->left;
		}
		cout<<root->data<<" ";
		while(root&&root->rtag==1){//开始找后继节点 
			root=root->right;
			cout<<root->data<<" ";
		}
		root=root->right;//没有后继了,说明有右子树 
	} 
}
int main(){
	tree node;
	create(node);
	pre=node;
	inOrderThreading(node); 
	inOrder(node); 
}

3后序线索化:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值