先序 中序 后序 线索二叉树

///有头结点版 + 无头结点版  啊啊啊啊啊啊 感觉自己快吐血了  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.


*/

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值