两种方式(这里主要讲述中序线索化)
数据结构与算法之二叉树的线索化
用土办法找到中序前驱(暴力)
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);//递归遍历左子树
visit(T);
InOrder(T->rchild);//递归遍历右子树
}
}
void visit(BiTNode *q){
if(q==p){
final = pre;//找到p的前驱
}else{
pre = q;
}
}
//辅助全局变量,用于查找结点p的前驱
BiTNode *p;//p指向目标结点
BiTNode * pre = NULL;//指向当前访问结点的前驱
BiTNode * final = NULL;//用于记录最终结果
中序线索化
先序线索化和后序线索化也参考此思路
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;//左右线索标志
}ThreadNode,*ThreadTree;
//全局变量pre,指向当前访问结点的前驱
ThreadNode *pre=NULL;
void InThread(ThreadTree T){
if (T!=NULL){
InThread(T->lchild);//中序遍历左子树
visit(T);//访问根节点
InThread(T->rchild);//中序遍历右子树
}
}
void visit(BiTNode *q){
if(q->lchild==NULL){//左子树为空,建立前驱线索
q->lchild=pre;
q->ltag=1;
}
if(pre!=NUll&&q->rchild==NULL){
pre.rchild=q;//建立前驱结点的后继线索
pre->rtag=1;
}
pre=q;
}
注意:最后还要检查
pre
的rchild
是否为NULL
,如果是,则令rtag=1;
全部代码展示
/**
* 二叉搜索树
* @author five-five
* @created 2022/6/1
*
*/
#include "stdio.h"
#include "stdbool.h"
#include "stdlib.h"
typedef struct ThreadNode {
int data;
struct ThreadNode *lChild;
struct ThreadNode *rChild;
int ltag;
int rtag;
} ThreadNode, *ThreadTree;
ThreadNode **preNode = NULL;
void preVisit(ThreadNode *pNode);
/**
* 前序线索化二叉树
* @param threadTree 二叉树
* @param pre 使用双重指针接受上结点
* @return ture?线索化成功:线索化失败
*/
bool preInitThreadTree(ThreadTree threadTree, ThreadNode **pre) {
if (threadTree == NULL) {
return false;
}
*pre = NULL;
//左子树
preInitThreadTree(threadTree, pre);
if (threadTree->lChild == NULL) {
threadTree->lChild = (*pre);
threadTree->ltag = 1;
}
//当前结点
if (*pre != NULL && (*pre)->rChild == NULL) {
*pre = threadTree->rChild;
(*pre)->rtag = 1;
}
*pre = threadTree;
//右结点
preInitThreadTree(threadTree->rChild, pre);
return true;
}
/**
* 先序遍历
* @param threadTree 要遍历的树
* @return true?成功:失败
*/
bool preOrder(ThreadTree threadTree) {
if (threadTree == NULL) {
return false;
}
preOrder(threadTree->lChild);
preVisit(threadTree);
preOrder(threadTree->rChild);
return true;
}
/**
* 先序遍历
* @param pNode 当前结点
* @param pre 前序结点指针
*/
void preVisit(ThreadNode *pNode) {
if (pNode == NULL) {
return;
}
if (pNode->lChild == NULL) {
pNode->lChild = (*preNode);
pNode->ltag = 1;
}
if ((*preNode) != NULL && (*preNode)->rChild == NULL) {
(*preNode)->rChild = pNode;
(*preNode)->rtag = 1;
}
(*preNode) = pNode;
}