先构建二叉树、中序线索化,然后函数实现求结点的前驱或者后继结点,利用后续结点实现对线索二叉树的中序遍历。
线索二叉树主要就是新增tag位,子树不空则置true。
关于中序遍历:在main函数中,先找到最左边的结点,然后依据该结点实现中序遍历。
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
typedef char datatype;
struct node {
node *lchild;
node *rchild;
bool ltag;
bool rtag;
datatype data;
};
typedef node *tBTREE;
node *pre = NULL;
//将二叉树--中序线索化
void InOrderTh(tBTREE BT) {
if (BT) {
InOrderTh(BT->lchild);
BT->ltag = (BT->lchild) ? true : false;
BT->rtag = (BT->rchild) ? true : false;
if (pre) {
if (pre->rtag == false)
pre->rchild = BT;
if (pre->ltag == false)
pre->lchild = pre;
}
pre = BT;
InOrderTh(BT->rchild);
}
}
//求结点P的后继结点 P$
node *InNext(node *P) {
node *Q;
Q = P->rchild;
if (P->rtag == true) {
while (Q->ltag == true)
Q = Q->lchild;
}
return Q;
}
//求结点P的前驱结点 $P
node *InLast(node *P) {
node *Q;
Q = P->lchild;
if (P->ltag == true) {
while (Q->rtag == true)
Q = Q->rchild;
}
return Q;
}
void visit(node *P) {
cout << P->data << " ";
}
//用InNext实现中序遍历二叉树:根结点后的中序遍历
void rearThInOrder(node *Head) {
node *temp;
for (temp = Head; temp != NULL; temp = InNext(temp) )
visit(temp);
}
void CreateBT(tBTREE &BT) {
char ch;
cin >> ch;
if (ch == '#')
BT = NULL;
else {
BT = new node;
BT->data = ch;
CreateBT(BT->lchild);
CreateBT(BT->rchild);
}
}
//在S后插入R
void RInsert(node *S, node *R) {
node *W;
R->rchild = S->rchild;
R->rtag = S->rtag;
R->lchild = S;
R->ltag = false;
S->rchild = R;
S->rtag = true;
if (R->rtag == true) {
W = InNext(R);
W->lchild = R;
}
}
int main() {
tBTREE BT;
node *q, *p;
cout << "输入先序遍历结点构建树:";
//ABDH##I##EJ###CF##G## 测试用例
CreateBT(BT);
InOrderTh(BT);
q = BT;
while (q->ltag == true) {
q = q->lchild;
}
//preThInOrder(BT);
cout << "中序线索二叉树的中序遍历:" << endl;
rearThInOrder(q);
node *R;
R = new node; //错误点 不可省略
R->data = 'K';
RInsert(BT, R);
p = BT;
while (p->ltag == true) {
p = p->lchild;
}
cout << endl << "在BT头结点后插入结点 R->data = K 后的中序遍历:" << endl;
rearThInOrder(p);
return 0;
}
主要参考: 《数据结构与算法》(第五版)张岩
《数据结构考研复习指导》(王道)