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后序线索化: