先序的倒序输出和后序的正序输出懒得写了
#include<stdio.h>
#include<stdlib.h>
typedef struct P {
int data;
struct P* l,* r;
int lt, rt;
}P, *p;
void Init(p* T, int e) {
p t = *T;
t = (p)malloc(sizeof(P));
t->data = e;
t->l = t->r = NULL;
t->lt = t->rt = 0;
(*T) = t;
}
void setTree(p* T, int e) {
p t = *T; int a, b, n, m;
if (t == NULL)Init(&t, e);
else t->data = e;
scanf_s("%d %d %d %d", &a, &b, &n, &m);//a、n为0则不建分支,b、m为值,若无则为0
if (a)setTree(&t->l, b);
if (n)setTree(&t->r, m);
(*T) = t;
}
void setTopInTread(p t, p* pre) {
p pr = *pre;//t为当前节点,pr为当前头节点
if (t) {
//setInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
pr = t;//更新头结点为当前节点
if (!t->lt)//左孩子可能会指向前趋,
setTopInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
if (!t->rt)//右孩子可能已经指向后继
setTopInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
}
(*pre) = pr;
}
void setLastInTread(p t, p* pre) {//建立线索二叉树
p pr = *pre;//t为当前节点,pr为当前头节点
if (t) {//中序遍历时左右孩子不可能先指向前趋或后继
if (!t->lt&& t->l)//防止pr变为NULL
setLastInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
if (!t->rt && t->r)
setLastInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
pr = t;//更新头结点为当前节点
}
(*pre) = pr;
}
void setMidInTread(p t, p* pre) {//建立线索二叉树
p pr = *pre;//t为当前节点,pr为当前头节点
if (t) {//中序遍历时左右孩子不可能先指向前趋或后继
setMidInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
pr = t;//更新头结点为当前节点
setMidInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
}
(*pre) = pr;
}
void createLastInTread(p t) {//开始建立线索二叉树
p pr = NULL;
if (t) {
setLastInTread(t, &pr);
//pr->r = NULL;//中序遍历末尾节点指向空
//pr->rt = 1;
}
}
void createMidInTread(p t) {//开始建立线索二叉树
p pr = NULL;
if (t) {
setMidInTread(t, &pr);
pr->r = NULL;//中序遍历末尾节点指向空
pr->rt = 1;
}
}
void createTopInTread(p t) {//开始建立线索二叉树
p pr = NULL;
if (t) {
setTopInTread(t, &pr);
pr->r = NULL;//中序遍历末尾节点指向空
pr->rt = 1;
}
}
p getMostLeft(p T) {//找到最左
while (T->lt == 0 && T->l)T = T->l;
return T;
}
p getMostRight(p T) {
while (!T->rt)T = T->r;
return T;
}
p getTopLast(p T) {
while (!T->lt || !T->rt)
if (!T->rt)T = T->r;
else if (!T->lt) T = T->l;
return T;
}
p getLastTop(p T) {
while (!T->lt || !T->rt)
if (!T->lt)T = T->l;
else if (!T->rt)T = T->r;
return T;
}
void print_last_Tree(p T) {
printf("后序线索二叉树不可直接找到后继");
}
void Lastprint_last_Tree(p T) {//线索后序倒叙遍历
for (p t = T; t; t = ((!t->lt||!t->rt)? (!t->rt?t->r: t->l) : t->l))
printf("%d ", t->data);
}
void print_top_Tree(p T) {//线索先序遍历
for (p t = T; t; t = (t->rt ? t->r : (t->lt ? t->r : t->l)))
printf("%d ", t->data);
}
void Lastprint_top_Tree(p T) {//线索先序倒叙遍历
printf("先序线索二叉树不可直接找到前驱");
}
void print_mid_Tree(p T) {//线索中序遍历
for (p t = getMostLeft(T); t; t = (!t->rt ? getMostLeft(t->r) : t->r))
printf("%d ", t->data);
}
void Lastprint_mid_Tree(p T) {//线索中序倒叙遍历
for (p t = getMostRight(T); t; t = (!t->lt ? getMostRight(t->l) : t->l))
printf("%d ", t->data);
}
void point_top(p T) {//正常遍历
printf("%d ", T->data);
if (T->l)point_top(T->l);
if (T->r)point_top(T->r);
}
void point_last(p T) {//正常遍历
if (T->l)point_last(T->l);
if (T->r)point_last(T->r);
printf("%d ", T->data);
}
void point_mid(p T) {//正常遍历
if (T->l)point_mid(T->l);
printf("%d ", T->data);
if (T->r)point_mid(T->r);
}
int main() {
p T = NULL, T1 = NULL, T2 = NULL;
int n;
scanf_s("%d", &n);
setTree(&T, n); setTree(&T1, n); setTree(&T2, n);
/*中序遍历*/
printf("中序遍历的正常、线索、倒叙线索:\n");
point_mid(T); printf("\n");
createMidInTread(T);
print_mid_Tree(T); printf("\n");
Lastprint_mid_Tree(T); printf("\n");
printf("*****************************\n");
/*先序遍历*/
printf("先序遍历的正常、线索、倒叙线索:\n");
point_top(T1); printf("\n");
createTopInTread(T1);
print_top_Tree(T1); printf("\n");
Lastprint_top_Tree(T1); printf("\n");
printf("*****************************\n");
/*后序遍历*/
printf("后序遍历的正常、线索、倒叙线索:\n");
point_last(T2), printf("\n");
createLastInTread(T2);
print_last_Tree(T2); printf("\n");
Lastprint_last_Tree(T2), printf("\n");
printf("*****************************\n");
return 0;
}
/*分别各建了一次树,懒得改了
1
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
*/