学数据结构的时候没有学线索二叉树,现在考研需要,补上了。
线索二叉树中给每个节点加上标记,使叶节点的空的数据域填上前驱或者后继,使得线索二叉树能快速的找到前驱后继。
线索化时如节点左子树为空,则添加前驱;设置全局变量pre,保存上一个访问的节点,访问下一个节点时,如果pre右子树为空,则pre的后继连上此节点。
#include先序线索二叉树#include #define N 100 typedef int ElemType; typedef struct ThreadNode{ ElemType data; struct ThreadNode *lchild,*rchild; int ltag,rtag; //左右线索 }ThreadNode,*ThreadTree; ThreadNode *pre=NULL; void visit(ThreadNode *q){ if(q->lchild==NULL){ q->lchild=pre; q->ltag=1; } if(pre&&pre->rchild==NULL){ pre->rchild=q; pre->rtag=1; } pre=q; } void InThread(ThreadTree T){ //边遍历边线索化 if(T){ InThread(T->lchild); visit(T); //后序调一下位置即可 InThread(T->rchild); } } void CreatInThread(ThreadTree T){ //线索化二叉树 pre=NULL; if(T){ InThread(T); if(pre->rchild==NULL){ //如果最后一点为空,给他加标记 pre->rtag=1; } } } ThreadNode *Firstnode(ThreadNode *p){ //p的第一个被中序遍历的节点 while(p->ltag==0) p=p->lchild; return p; } ThreadNode *Nextnode(ThreadNode *p){ //中序线索二叉树中p的后继 if(p->rtag==0) return Firstnode(p->rchild); else return p->rchild; } void Inoder(ThreadNode *T){ //非递归中序遍历二叉树 ThreadNode *p; for(p=Firstnode(T);p!=NULL;p=Nextnode(p)){ printf("%d ",p->data); } printf("n"); } ThreadNode *Lastnode(ThreadNode *p){ //p的最后一个被中序遍历的节点 while(p->rtag==0) p=p->rchild; return p; } ThreadNode *Prenode(ThreadNode *p){ //中序线索二叉树中p的前继 if(p->ltag==0) return Lastnode(p->lchild); else return p->lchild; } void RevInoder(ThreadNode *T){ //非递归逆向中序遍历二叉树 ThreadNode *p; for(p=Lastnode(T);p!=NULL;p=Prenode(p)){ printf("%d ",p->data); } printf("n"); } ThreadTree Creat(ThreadTree T,int x){ if(!T){ ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode)); T->data=x; T->lchild=T->rchild=NULL; T->ltag=T->rtag=0; } else { if(x>T->data){ T->rchild=Creat(T->rchild,x); } else{ T->lchild=Creat(T->lchild,x); } } } int main() { int i,j,k; int a[10]={2,5,6,9,3,4,7,8,1,0}; ThreadTree T; for(i=0;i<9;i++){ T=Creat(T,a[i]); } CreatInThread(T); Inoder(T); RevInoder(T); return 0; }
先序线索二叉树实现同中序基本一致,要注意的点是左边节点的数据可能是线索并不是真正的左子树,所以在遍历的时候加上一个判断条件。
#include后序线索二叉树#include #define N 100 typedef int ElemType; typedef struct ThreadNode{ ElemType data; struct ThreadNode *lchild,*rchild; int ltag,rtag; //左右线索 }ThreadNode,*ThreadTree; ThreadNode *pre=NULL; void visit(ThreadNode *q){ if(q->lchild==NULL){ q->lchild=pre; q->ltag=1; } if(pre&&pre->rchild==NULL){ pre->rchild=q; pre->rtag=1; } pre=q; } void PreThread(ThreadTree T){ //边遍历边线索化 if(T){ visit(T); if(T->ltag==0){ //防止左边为线索无限循环的问题 PreThread(T->lchild); } PreThread(T->rchild); } } void CreatPreThread(ThreadTree T){ //线索化二叉树 pre=NULL; if(T){ PreThread(T); if(pre->rchild==NULL){ //如果最后一点为空,给他加标记 pre->rtag=1; } } } ThreadTree Creat(ThreadTree T,int x){ if(!T){ ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode)); T->data=x; T->lchild=T->rchild=NULL; } else { if(x>T->data){ T->rchild=Creat(T->rchild,x); } else{ T->lchild=Creat(T->lchild,x); } } } ThreadNode *NextNode(ThreadNode *p){ //先序二叉树的后继 if(p->rtag==1) return p->rchild; else { if(p->lchild) return p->lchild; else return p->rchild; } } int main() { int i,j,k; int a[10]={2,5,6,9,3,4,7,8,1,0}; ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode)); T->data=a[0]; T->lchild=T->rchild=NULL; for(i=1;i<9;i++){ T=Creat(T,a[i]); } CreatPreThread(T); printf("%d",NextNode(T)->data); return 0; }
后序线索二叉树同中序线索二叉树实现基本一致,遍历的时候调一下顺序就可。
#include#include #define N 100 typedef int ElemType; typedef struct ThreadNode{ ElemType data; struct ThreadNode *lchild,*rchild; int ltag,rtag; //左右线索 }ThreadNode,*ThreadTree; ThreadNode *pre=NULL; void visit(ThreadNode *q){ if(q->lchild==NULL){ q->lchild=pre; q->ltag=1; } if(pre&&pre->rchild==NULL){ pre->rchild=q; pre->rtag=1; } pre=q; } void PostThread(ThreadTree T){ //边遍历边线索化 if(T){ visit(T); if(T->ltag==0){ //防止左边为线索无限循环的问题 PostThread(T->lchild); } PostThread(T->rchild); } } void CreatPostThread(ThreadTree T){ //线索化二叉树 pre=NULL; if(T){ PostThread(T); if(pre->rchild==NULL){ //如果最后一点为空,给他加标记 pre->rtag=1; } } } ThreadTree Creat(ThreadTree T,int x){ if(!T){ ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode)); T->data=x; T->lchild=T->rchild=NULL; } else { if(x>T->data){ T->rchild=Creat(T->rchild,x); } else{ T->lchild=Creat(T->lchild,x); } } } ThreadNode *PreNode(ThreadNode *p){ if(p->ltag==1) return p->lchild; else { if(p->rchild) return p->rchild; else return p->lchild; } } int main() { int i,j,k; int a[10]={2,5,6,9,3,4,7,8,1,0}; ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode)); T->data=a[0]; T->lchild=T->rchild=NULL; for(i=1;i<9;i++){ T=Creat(T,a[i]); } CreatPostThread(T); printf("%d",PreNode(T)->data); return 0; }



