目錄
一、用土方法找到中序前驅
//中序遍歷
void InOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild); //遞歸遍歷左子樹
visit(T); //訪問根結點
InOrder(T->rchild); //遞歸遍歷右子樹
}
}
//訪問結點q
void visit(BiTNode * q){
if(q == p) //當前訪問結點剛好是結點p
final = pre; //找到p的前驅
else
pre = q; //pre指向當前訪問的結點
}
//輔助全局變量,用於查找結點p的前驅
BiTNode *p; //p指向目標結點
BiTNode *pre = NULL; //指向當前訪問結點的前驅
BiTNode *final = NULL; //用於記錄最終結果
二、中序線索化
//全局變量pre,指向當前訪問結點的前驅
ThreadNode *pre = NULL;
//中序線索化二叉樹T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化爲NULL
if(T != NULL){ //非空二叉樹才能線索化
InThread(T); //中序線索化二叉樹
if(pre->rchild == NULL)
pre->rtag = 1; //處理遍歷的最後一個結點
}
}
//線索二叉樹結點
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右線索標誌
}ThreadNode,*ThreadTree;
//中序遍歷二叉樹,一邊遍歷一邊線索化
void InThread(ThreadTree T){
if(T != NULL){
InThread(T->lchild); //中序遍歷左子樹
visit(T); //訪問根節點
InThread(T->rchild); //中序遍歷右子樹
}
}
void visit(ThreadNode *q){
if(q->lchild == NULL){ //左子樹爲空,建立前驅線索
q->lchild = pre;
q->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = q; //建立前驅結點的後繼線索
pre->rtag = 1;
}
pre = q;
}
三、中序線索二叉樹
四、中序線索化(王道教材版)
//中序線索化
void InThread(ThreadTree p,ThreadTree &pre){
if(p != NULL){
InThread(p->lchild,pre); //遞歸、線索化左子樹
if(p->lchild == NULL){ //左子樹爲空,建立前驅線索
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = p; //建立前驅結點的後繼線索
pre->rtag = 1;
}
pre = p;
InThread(p->rchild,pre);
}
}
//中序線索二叉樹T
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){
InThread(T,pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
五、先序線索化
//全局變量pre,指向當前訪問結點的前驅
ThreadNode *pre = NULL;
//中序線索化二叉樹T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化爲NULL
if(T != NULL){ //非空二叉樹才能線索化
InThread(T); //中序線索化二叉樹
if(pre->rchild == NULL)
pre->rtag = 1; //處理遍歷的最後一個結點
}
}
//線索二叉樹結點
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右線索標誌
}ThreadNode,*ThreadTree;
//中序遍歷二叉樹,一邊遍歷一邊線索化
void InThread(ThreadTree T){
if(T != NULL){
visit(T); //訪問根節點
if(T->ltag == 0)
InThread(T->lchild); //中序遍歷左子樹
InThread(T->rchild); //中序遍歷右子樹
}
}
void visit(ThreadNode *q){
if(q->lchild == NULL){ //左子樹爲空,建立前驅線索
q->lchild = pre;
q->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = q; //建立前驅結點的後繼線索
pre->rtag = 1;
}
pre = q;
}
六、先序線索化(王道教材版)
//中序線索化
void InThread(ThreadTree p,ThreadTree &pre){
if(p != NULL){
if(p->lchild == NULL){ //左子樹爲空,建立前驅線索
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = p; //建立前驅結點的後繼線索
pre->rtag = 1;
}
pre = p;
if(p->ltag == 0)
InThread(p->rchild,pre);
InThread(p->lchild,pre); //遞歸、線索化左子樹
}
}
//先序線索二叉樹T
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){
InThread(T,pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
七、後序線索化
//全局變量pre,指向當前訪問結點的前驅
ThreadNode *pre = NULL;
//中序線索化二叉樹T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化爲NULL
if(T != NULL){ //非空二叉樹才能線索化
InThread(T); //中序線索化二叉樹
if(pre->rchild == NULL)
pre->rtag = 1; //處理遍歷的最後一個結點
}
}
//線索二叉樹結點
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右線索標誌
}ThreadNode,*ThreadTree;
//中序遍歷二叉樹,一邊遍歷一邊線索化
void InThread(ThreadTree T){
if(T != NULL){
InThread(T->lchild); //中序遍歷左子樹
InThread(T->rchild); //中序遍歷右子樹
visit(T); //訪問根節點
}
}
void visit(ThreadNode *q){
if(q->lchild == NULL){ //左子樹爲空,建立前驅線索
q->lchild = pre;
q->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = q; //建立前驅結點的後繼線索
pre->rtag = 1;
}
pre = q;
}
八、後序線索化(王道教材版)
//後序線索化
void PostThread(ThreadTree p,ThreadTree &pre){
if(p != NULL){
PostThread(p->lchild,pre);
PostThread(p->rchild,pre);
if(p->lchild == NULL){
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && p->rchild == NULL){
pre->rchild = p;
pre->rtag = 1;
}
pre = p;
}
}