中序线索化的线索二叉树的前序遍历、中序遍历和后序遍历
前序遍历的后继结点:
(1)P的左子树不为空,此时P的后继结点就是P的左儿子;
(2)P的左子树为空但右子树不为空,此时P的后继结点就是P的右儿子;
(3)P的左右子树均为空,此时在从P开始的右线索序列中,第一个有右儿子的节点的右儿子或者头结点就是P的后继结点。
中序遍历的后继结点:
若一个节点的右子树为空,此时右线索所指节点即为所求;若这个节点的右子
树不为空,此时它的后继结点是其右子树的最左节点。
后序遍历的后继结点:
当一个节点是它的双亲节点的右孩子时,它的后序遍历的后继就是双亲节点。当它是双亲节点的左孩子,且双亲节点没有右子树时,它的后序遍历的后继也是双亲节点。当它是双亲节点的左孩子,且双亲节点有右子树时,它的后序遍历的后继是双亲节点右子树中的最左节点。
脑子已被搅乱,为了节省代码量和简化过程,后序遍历采用了递归的方法,请见谅。
- #include<stdio.h>
- //输入样例:1 2 3 0 0 4 0 5 0 0 6 0 0
- typedef enum {Link, Thread} PointerTag;//指针标志
- typedef int DataType;
- typedef struct BiThreTree //定义节点
- {
- PointerTag LTag, RTag;
- DataType data;
- struct BiThreTree *lchild, *rchild;
- }BiThreTree;
- BiThreTree *pre; //全局变量,用于二叉树的线索化
- BiThreTree *CreateTree() //按先序输入建立二叉树
- {
- BiThreTree *T;
- DataType e;
- scanf("%d", &e);
- if(e==0)
- T=NULL;
- else
- {
- T=new BiThreTree;
- T->data=e;
- T->LTag=Link; //初始化时指针标志均为Link
- T->RTag=Link;
- T->lchild=CreateTree();
- T->rchild=CreateTree();
- }
- return T;
- }//
- void InThread(BiThreTree *T)//对二叉树进行中序线索化的算法
- {
- BiThreTree *p;
- p=T;
- if(p)
- {
- InThread(p->lchild);//左子树线索化
- if(!p->lchild)//if左子树为空
- {
- p->LTag=Thread;
- p->lchild=pre;
- }
- if(!pre->rchild)//if右子树为空
- {
- pre->RTag=Thread;
- pre->rchild=p;
- }
- pre=p;//前驱指向当前节点
- InThread(p->rchild);//右子树线索化
- }
- }//
- BiThreTree *InOrderThrTree(BiThreTree *T)//中序线索化二叉树
- {
- BiThreTree *Thre; //Thre为头结点的指针
- Thre=new BiThreTree;
- Thre->lchild=T;
- Thre->rchild=Thre;
- pre=Thre;
- InThread(T);
- pre->RTag=Thread;
- pre->rchild=Thre;
- Thre->rchild=pre;
- return Thre;
- }//
- void InThrTravel(BiThreTree *Thre)//中序遍历二叉树
- {
- BiThreTree *p;
- p=Thre->lchild;//Thre是树的"头"
- while(p!=Thre)//指针回指向头结点时结束
- {
- while(p->LTag==Link)//Link表示子树存在
- p=p->lchild;
- printf("%4d", p->data);
- while(p->RTag==Thread&&p->rchild!=Thre)//Thread表示右子树不存在,存在的"右子树"是线索
- {
- p=p->rchild;
- printf("%4d", p->data);
- }
- p=p->rchild;
- }
- }//
- void FirstThrTravel(BiThreTree *Thre)//先序遍历线索二叉树
- {
- BiThreTree *p;
- p=Thre->lchild;
- while(p!=Thre)
- {
- printf("%4d", p->data);
- while(p->LTag==Link)
- {
- p=p->lchild;
- printf("%4d", p->data);
- }
- if(p->RTag==Thread)
- {p=p->rchild;}
- if(p->RTag==Link)
- {p=p->rchild;}
- }
- }//
- void LastThrTravel(BiThreTree *p)//递归实现后序遍历线索二叉树
- {
- if(p!=NULL)
- {
- if(p->LTag==Link)
- LastThrTravel(p->lchild);
- if(p->RTag==Link)
- LastThrTravel(p->rchild);
- printf("%4d", p->data);
- }
- }
- int main()
- {
- BiThreTree *T, *Thre;
- printf("请按前序遍历输入线索二叉树的元素,用0代表空儿子:\n");
- //1 2 3 0 0 4 0 5 0 0 6 0 0
- T=CreateTree();
- Thre=InOrderThrTree(T);
- printf("\n中序遍历该线索二叉树的结果为:\n");
- InThrTravel(Thre);
- printf("\n先序遍历该线索二叉树的结果为:\n");
- FirstThrTravel(Thre);
- printf("\n后序遍历该线索二叉树的结果为:\n");
- LastThrTravel(Thre->lchild);
- getchar();
- return 0;
- }
转载于:https://blog.51cto.com/4802380/1156314