///有头结点版 + 无头结点版 啊啊啊啊啊啊 感觉自己快吐血了 T^T
#include<iostream>
#include<queue>
using namespace std;
typedef struct treenode{
char data;
treenode *lchild;
treenode *rchild;
int LTag;
int RTag;
}node, *Tree;
node *pre;
node *create_tree(node *t){
char a;
cin >> a;
if(a == '0')
return NULL;
t = new node;
t->LTag = 0;
t->RTag = 0;
t->data = a;
t->lchild = create_tree(t->lchild);
t->rchild = create_tree(t->rchild);
return t;
}
void pre_order(node *t){
if(t){
cout << t->data;
pre_order(t->lchild);
pre_order(t->rchild);
}
}
///******************in_order**************************
void in_order_threading(Tree t){
if(t){
in_order_threading(t->lchild);
if(t->lchild == NULL){
t->lchild = pre;
t->LTag = 1;
}
if(pre && pre->rchild == NULL){
pre->rchild = t;
pre->RTag = 1;
}
pre = t;
in_order_threading(t->rchild);
}
}
node * in_thread(node *p, Tree t){
p = new node;
p->LTag = 0;
p->RTag = 1;
p->rchild = p;
if(t == NULL){
p->lchild = p;
}
else{
p->lchild = t;
pre = p;
in_order_threading(t);
p->rchild = pre;
pre->RTag = 1;
pre->rchild = p;
}
return p;
}
void in_order_traverse(node *p){
node *t;
t = p->lchild;
while(t!=p){
while(t->LTag == 0){///走到最左
t = t->lchild;
}
cout << t->data;///打印最左边的
while(t->RTag == 1 && t->rchild!=p){
t = t->rchild;///顺着线索去打印
cout << t->data;
}
t = t->rchild;
}
}
///**************pre_order*************************
void pre_order_threading(Tree t){
if(t){
if(t->lchild==NULL){
t->lchild = pre;
t->LTag = 1;
}
if(pre && pre->rchild == NULL){
pre->rchild = t;
pre->RTag = 1;
}
pre = t;
if(t->LTag == 0)/// 之前写的是t->lchild 死循环了 这两个不是等价吗???
pre_order_threading(t->lchild);///终于在写后序的时候反应过来了。。。
if(t->RTag == 0)///因为我们已经把空的t->lchild赋值了 其他的是没关系的
pre_order_threading(t->rchild);///但是有一个是NULL 就是说 t->LTag == 1
}///但是t->lchild == NULL 也就是说 只有t->LTag==0 t->lchild才一定不空
return;///不管你明不明白 反正我是明白了~ 唉 困扰了我一下午的问题啊 竟然在一瞬间就有了灵感~
}
node *pre_thread(node *p, Tree t){
p = new node;
p->LTag = 0;
p->RTag = 1;
p->rchild = p;
if(t==NULL){
p->lchild = p;
}
else{
p->lchild = t;
pre = p;
pre_order_threading(t);
p->rchild = pre;
pre->RTag = 1;///现在pre是最后一个节点啦
pre->rchild = p;
}
return p;
}
void pre_order_traverse(node *p){
node *t;
t = p->lchild;
while(t!=p){
while(t->LTag == 0){
cout << t->data;
t = t->lchild;
}
cout << t->data;
while(t->RTag == 1 && t->rchild!=p){
t = t->rchild;
cout << t->data;
}
t = t->rchild;
}
}
///**************post_order*********************
void post_order_threading(Tree t){
if(t){
post_order_threading(t->lchild);
post_order_threading(t->rchild);
if(t->lchild == NULL){
t->lchild = pre;
t->LTag = 1;
}
if(pre&&pre->rchild == NULL){
pre->rchild = t;
pre->RTag = 1;
}
pre = t;
}
}
node *parent(node *t, node *p){
if(t){
queue<node *>q;
while(!q.empty())
q.pop();
q.push(t);
while(!q.empty()){
node *a = q.front();
q.pop();
if(a->lchild == p || a->rchild == p){
return a;
}
if(a->lchild)
q.push(a->lchild);
if(a->rchild)
q.push(a->rchild);
}
}
return NULL;
}
void post_order_traverse(node* t)
{
if (t)
{
node* p = t;
pre = NULL;
while (p)
{
while ( p->lchild != pre && p->LTag == 0)///走到最左
{
p = p->lchild;
}
/// p->data == d
while (p && p->RTag== 1)///顺着线索走
{
cout << p->data;
pre = p;
p = p->rchild;
}
if (p == t)///若p回到了根节点
{
cout << p->data;
return;
}
while (p && p->rchild == pre)
{
cout << p->data;
pre = p;
node *s = parent(t, p);
p = s;
}
if (p && p->RTag == 0)
{
p = p->rchild;
}
}
}
}
int main(){
node *t;
node *p;
t = create_tree(t);
cout << "先序遍历:";
pre_order(t);
cout << endl;
cout << "中序线索化:";
p = in_thread(p, t);
in_order_traverse(p);
cout << endl;
t = create_tree(t);
cout << "先序线索化:";
p = pre_thread(p, t);
pre_order_traverse(p);
cout << endl;
t = create_tree(t);
cout << "后序线索化:";
post_order_threading(t);
post_order_traverse(t);
cout << endl;
return 0;
}
/*
ab0d00ce000
先序遍历:abdce
中序线索化:bdaec
ab0d00ce000
先序线索化:abdce
ab0d00ce000
后序线索化:dbeca
Process returned 0 (0x0) execution time : 22.250 s
Press any key to continue.
*/
先序 中序 后序 线索二叉树
最新推荐文章于 2024-07-29 08:47:18 发布