中序线索二叉树思路:
首先找到中序二叉树的第一个要访问的结点(p->ltag==0) 就让 p=p->lchild; 退出时候,就是第一个要访问的结点p
找p结点的next结点,如果结点p没有右孩子(即p->rtag==1), 说明p结点的next结点就是线索化的p->rchild,因为线索化后p->rchild指向下一个结点,找到了next结点, 当p->rtag==0时候,说明说明他有右孩子,如果有右孩子,则右孩子作为一个子树,遍历这子树找到中序要遍历的第一个结点 重复这样操作. (一句话,中序,当有右孩子时候,把右孩子作为棵二叉树,找到这个二叉树根据中序遍历要访问的第一个结点就是要找的next结点,如果没有右孩子,则当前结点的右孩子就是要找到next结点)
中序遍历线索化二叉树:
//以当前结点为根节点,找到这个结点根据中序遍历要访问的第一个结点
node* Firstnode(node *p){
while(p->ltag == 0){
p = p->lchild;
}
return p;
}
//找到当前结点的下一个结点
node* Nextnode(node *p){
//如果p结点有右孩子,那么就找到结点p右孩子的第一个结点
if(p->rtag==0){
node *q = Firstnode(p->rchild);
return q;
}
else{
node *q = p->rchild;
return q;
}
}
//访问当前结点
void visit(node *p){
cout<<p->data<<" ";
}
//中序遍历线索化二叉树
void InOrder(node *root){
for(node *p=Firstnode(root); p!=NULL; p=Nextnode(p)){
visit(p);
}
}
前序线索二叉树:
node *p = root 让p结点指向根结点。
前序遍历的思路: 当p结点有左孩子的时候,则访问p结点,并将左孩子赋值给p,当没有左孩子时候,先访问p结点,因为p->ltag!=0,没有进入循环,没有访问到这个p,所以退出内层循环需要先访问p结点 左孩子访问结束后,该访问p的下一个结点了,因为是线索化的,如果有右孩子,因为左孩子已经访问结束了,就访问右孩子,如果没有右孩子,线索化二叉树的右孩子下一个结点.
void preOrder(node *bt){
if(bt==NULL){
return;
}
node *p = bt;
while(p!=NULL){ //表示p没有指向最后一个结点,因为线索二叉树最后一个结点由pre单独设置为NULL
while(p->ltag==0){
visit(p);
p = p->lchild;
}
visit(p);
p = p->rchild;
}
}