树——二叉树——线索二叉树

一、线索二叉树
(1)什么是线索化

将二叉树以某种次序将其遍历, 得到线性序列, 就是将非线性结构进行线索化

线索化的优点就是可以很快地得到前驱或后继。

如果保存线索化的线性序列

保存二叉树地线索化序列的其中一种方法就是在结点上加两个指针, 一个指向前驱一个指向后继, 这样的缺点就是存储密度大大降低。另一种方法就是加两个标记 充分利用空指针。

实现方法一
存储结构
leftLTagdataRTagright
//存储结构
typedef enum {Link, Thread} PointerTag; // 枚举 标志
typedef struct node
{
    char data;
    int LTag;
    int RTag;
    struct node *left, *right;

}*Node;

以这种结构构成的二叉链表作为二叉树的存储结构, 叫做线索链表,其中指向前驱和后继的指针叫做线索。加上线索的二叉树称之为线索二叉树

中序的实现代码
#include<bits/stdc++.h>
using namespace std;
typedef enum {Link, Thread} PointerTag; // 枚举 标志
typedef struct node
{
    char data;
    int LTag;
    int RTag;
    struct node *left, *right;

}*Node;

char preOrder[60];
int i;

// 每次建树的时候初始化左右Tag为 Link
Node pre;// 指向上一个被访问的结点

void inOrder(Node T)// 通过中序遍历 构建 中序的线索二叉树
{
    if(!T)return ; // 如果当前结点为空 直接返回

    inOrder(T->left);// 中序遍历左子树

    if(!T->left) //  处理当前结点的 前驱指针
    {
        T->LTag = Thread;
        T->left = pre;

    }
    if(!pre->right)  // 处理上一个结点的后继指针
    {
        pre->RTag = Thread;
    }
    pre = T;
    inOrder(T->right); // 中序遍历右子树
}

void inOrderThread(Node T)// 线索二叉树的遍历
{
    Node p = T->left;

    while(p != T)
    {
        while(p->LTag == Link)p = p->left; // 找最左下角的

        print("%c", p->data); // 访问最左下角的


        while(p->RTag == Thread && p->right != T)// 如果右子树是线索 并且不指向T(T是树的根的前驱辅助结点)
        {
            p = p->right;// 指向右子树
            printf("%c", p->data);// 访问
        }

        p = p->right;// 如果右右子树是儿子 那么就指向儿子 重复循环
    }

}

void create()
{

}

void init()
{
    i = 0;
}

int main()
{
    ios_base::sync_with_stdio(false);
    while(cin>>s)
    {
        init();
        Node root = create();//建树
        Node T = (Node)malloc(sizeof(node));// 创建辅助的头结点
        pre = T;
        

    }

    return 0;
}

实现方法二

先序的线索二叉树的代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct node // 结点
{
    char data;
    struct node *left,*right;
    struct node * last, *next;// 指向  前驱 和后继
}node, *Node;
int i;
char s[56];
Node Last;

Node create()
{
    if(s[i] == ',')
    {
        i++;
        return NULL;
    }

    Node T = (Node)malloc(sizeof(node));
    T->data = s[i++];
    T->left = create();
    T->right = create();
    T->next = NULL;
    T->last = NULL;

    return T;
}

void preOrder(Node T)
{
    if(!T)return;


    T->last = Last;
    Last->next = T;
    Last  = T;
    preOrder(T->left);
    preOrder(T->right);


}
int main()
{
    ios_base::sync_with_stdio(false);

    while(cin>>s)
    {
        i = 0;
        Node root = create();

        Node T  = (Node)malloc(sizeof(node));

        T->left = NULL;
        T->right = NULL;
        T->last = NULL;
        T->next = root;
        Last = T;
        preOrder(root);

        Node tmp = T;

        while(tmp->next)
        {
            printf("%c",tmp->next->data);
            tmp = tmp->next;
        }
    }

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值