线索二叉树

来源:互联网 发布:16总决赛骑士数据 编辑:程序博客网 时间:2024/06/05 19:56
#include<stdio.h>
#include<stdlib.h>


typedef char ElemType;
//线索存储标志位
//Link也就是0 表示指向左右孩子的指针
//Thread也就是1 表示指向前驱后继的线索
typedef enum {Link,Thread} PointerTag;


typedef struct BiThrNode
{
    char data;
    struct BiThrNode *lchild,*rchild;
    PointerTag ltag;
    PointerTag rtag;
}BiThrNode,*BiThrTree;


//全局变量始终指向刚刚访问过的节点
BiThrTree pre;


//创建一棵二叉树,约定用户遵照前序遍历的方式插入数据
void CreateBiThrTree(BiThrTree *T)
{
    char c;
    scanf("%c",&c);
    if(' '==c)
    {
        *T=NULL;
    }else{
        *T=(BiThrNode *) malloc(sizeof(BiThrNode));
        (*T)->data=c;
        (*T)->ltag=Link;  //默认都有左右孩子
        (*T)->rtag=Link;


        CreateBiThrTree(&(*T)->lchild);
        CreateBiThrTree(&(*T)->rchild);
    }


}


void InThreading(BiThrTree T)
{
    if(T)
    {
        InThreading(T->lchild);   //递归左孩子线索化
        if(!T->lchild){  //如果该节点没有左孩子,设置ltag为Thread 并把lchild指向上一个访问的节点(前驱)
            T->ltag=Thread;
            T->lchild=pre;
        }
        if(!pre->rchild)
        {
            pre->rtag=Thread;
            pre->rchild=T;
        }
        pre=T;
        InThreading(T->rchild);   //递归右孩子线索化
    }
}
void InOrderThreading(BiThrTree *p,BiThrTree T)
{
    *p=(BiThrNode *)malloc(sizeof(BiThrNode)); //为头指针 指向树根
    (*p)->ltag=Link;
    (*p)->rtag=Thread;
    (*p)->rchild=*p;
    if(!T)
    {
        (*p)->lchild=*p;   //空树指向自己
    }
    else{
        (*p)->lchild=T;  //指向树根
        pre=*p;  //pre赋值
        InThreading(T);
        pre->rchild=*p;  //收尾工作
        pre->rtag=Thread;
        (*p)->rchild=pre;
    }
}
void visit(char c)
{
    printf("%c",c);
}
//中序遍历二叉树 非递归
void InOrderTraverse(BiThrTree T)
{
    BiThrTree p;
    p=T->lchild;
    while(p!=T)
    {
        while(p->ltag==Link)
        {
            p=p->lchild;
        }
        visit(p->data);
        while(p->rtag==Thread && p->rchild!=T)
        {
            p=p->rchild;
            visit(p->data);
        }
        p=p->rchild;
    }


}
int main()
{
    BiThrTree P,T=NULL;
    CreateBiThrTree(&T);
    InOrderThreading(&P,T);
    printf("中序遍历结果为:\n");
    InOrderTraverse(P);  //传入头指针
    return 0;
}