不带头结点的线索二叉树(C语言版) 线索化、遍历操作 超详细!

#include
#include

// 线索二叉树的存储结构
typedef struct thread_node
{
    char data;
    struct thread_node* lchild;//线索
    struct thread_node* rchild;
    int ltag;
    int rtag;
}thread_node, *thread_tree;

int cur;//现在指向的结点
char str[1000];//数组存放遍历字符串

//创建二叉树
thread_node* create_tree()//创建树
{
    cur++;//指向下一个
    if(str[cur] == '#')//如果碰到#,则表示该子树是空结点
    {
        return NULL;
    }
    thread_node* root = (thread_node*)malloc(sizeof(thread_node));//不是空结点的话,给结点分配空间
    root -> data = str[cur];//数据域赋值
    root -> lchild = create_tree();//递归 左子树相同方法创建树
    root -> rchild = create_tree();//递归 右子树相同方法创建树
    return root;
}

//中序线索二叉树的构造
void mid_thread(thread_tree tree, thread_node** pre)
{
    if(tree != NULL)
    {

        mid_thread(tree->lchild, pre);

        //与前序结点简历线索
        if(tree->lchild == NULL) // 为空建立线索
        {
            tree->lchild = (*pre); // ①①① 对应下面的 ①①① ,代表最左下角节点的前驱节点指向了头节点 根据课本 P129 图b 所示
            tree->ltag = 1;
        }
        else
        {
            tree -> ltag = 0; // 表示不是线索
        }

        //前序结点与其后继结点(此结点)建立线索
        if((*pre) != NULL && (*pre) -> rchild == NULL) // pre->rchild == NULL 说明需要建立后继节点
        {
            (*pre)->rchild = tree;
            (*pre)->rtag = 1;
        }
        else
        {
            if((*pre) != NULL) // 重要!!! 不要忘记判断,因为初始时(*pre) 为 NULL,没有rtag
                (*pre) -> rtag = 0;
        }

        (*pre) = tree; //标记当前结点为刚访问的结点
        mid_thread(tree->rchild, pre);

    }
}

int main()
{
    char t;
    int start = 0;
    while(1)
    {
        scanf("%c", &t);
        if(t == '\n')
            break;
        str[start] = t;
        start++;
    }
    cur = -1;
    thread_node* tree = create_tree();


    /********************* 根据 P129 图a 建立不带头节点的线索二叉树 ***************************/
    thread_node* pre = NULL;
    mid_thread(tree, &pre); // 出来之后 (*pre) 是最右边的节点
    pre -> rchild = NULL; //


    /***********************遍历线索二叉树*************************/
    thread_node* cur2 = tree; // cur(current)代表当前节点,头节点的左节点为树的根节点 和上面的 ②②② 对应
    while(cur2 != NULL) // 因为树的最右边的根节点的右子树指向head节点,和 ③③③ 对应
    {
        while(cur2 -> ltag == 0)
            cur2 = cur2 -> lchild; // 沿着左子树一直往下找,其实是为了找到一个含有右线索的节点
        printf("%c ", cur2 -> data);

        while(cur2 -> rtag == 1 && cur2 -> rchild != NULL)
        {//不断找后继结点并打印出来
            cur2 = cur2 -> rchild;
            printf("%c ", cur2 -> data);
        }

        cur2 = cur2 -> rchild; // 往右边找
    }
}

//输入样例:HDA##C#B##GF#E###

不带头结点的线索二叉树(C语言版) 线索化、遍历操作 超详细!_第1张图片

如有错误欢迎指正~!

你可能感兴趣的:(数据结构,考研)