转自:http://blog.csdn.net/flying0033/article/details/6937477
后序线索二叉树的线索化有些麻烦:
1:若节点是二叉树的根,则后继为空;
2:若节点X是双亲的右孩子或者是双亲的左孩子且双亲没有右子树,则后继为双亲节点;
3:若双亲有左孩子而且双亲有右孩子,则后继为双亲右子树上面按后序遍历列出的第一个节点。
#include<stdio.h> #include<stdlib.h> #include<math.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef enum{Link,Thread} PointTag; typedef char Element; typedef int Status; typedef struct Node{ Element data; struct Node* left; //指向左孩子 struct Node* right; //指向右孩子 PointTag Ltag; //左右标志 PointTag Rtag; }BitNode,*BitTree; Status visit(Element e); Status CreateTree(BitTree *T); void InThreading(BitTree T); void InOrderThreading(BitTree *H,BitTree T); void InOrderTraverse_Thr(BitTree L); BitTree pre; Status visit(Element e) { printf("%c ",e); return OK; } Status CreateTree(BitTree *T) //前序创建二叉树 { Element ch; scanf("%c",&ch); if(ch == '#') (*T) = NULL; else { (*T) = (BitTree)malloc(sizeof(BitNode)); if(!(*T)) exit(OVERFLOW); (*T)->data = ch; (*T)->Ltag = Link; (*T)->Rtag = Link; CreateTree(&(*T)->left); CreateTree(&(*T)->right); } return OK; } void InThreading(BitTree p) //后序线索二叉树 { if(p) { InThreading(p->left); InThreading(p->right); if(!p->left) { p->left = pre; p->Ltag = Thread; } if(!pre->right) { pre->right = p; pre->Rtag = Thread; } pre = p; } } void InOrderThreading(BitTree *H,BitTree T) //创建头节点,后序线索二叉树 { (*H) = (BitTree)malloc(sizeof(BitNode)); if(!(*H)) exit(OVERFLOW); (*H)->right = (*H); (*H)->Rtag = Link; if(!T) { (*H)->left = (*H); (*H)->Ltag = Link; } else { pre = (*H); (*H)->left = T; (*H)->Ltag = Link; InThreading(T); (*H)->right = pre; } } BitTree Parent(BitTree Thr,BitTree p) //取得节点的父节点 { BitTree temp = Thr; if(temp->left == p) return temp; else { temp = temp->left; while(temp->left != p && temp->right != p) { if(temp->Rtag == Link) temp = temp->right; else temp = temp->left; //有左孩子去左孩子,没有左孩子,去前驱; } } return temp; } void InOrderTraverse_Thr(BitTree Thr) { BitTree temp = Thr->left; BitTree par = NULL; while(TRUE) { while(temp->Ltag == Link) temp = temp->left; if(temp->Rtag == Link) temp = temp->right; else break; } while(temp != Thr) { visit(temp->data); par = Parent(Thr,temp); //获得节点temp的父节点 if(par == Thr) //若父节点是Thr则节点temp为根节点,无后继 temp = Thr; else if(par->Rtag == Thread || temp == par->right) //无右兄弟的左节点或是右儿子 temp = par; else //节点temp是左孩子,且有右兄弟 { while(par->Rtag == Link) { par = par->right; while(par->Ltag == Link) { par = par->left; } } temp =par; } } } int main() { BitTree H,T; printf("请输入前序二叉树的数据,例('ABDH##I##EJ###CF##G##')\n"); CreateTree(&T); InOrderThreading(&H,T); InOrderTraverse_Thr(H); return 0; }