线索中序二叉树

线索中序二叉树

1.节点的结构

typedef struct node
{
    int lefttype;//左孩子类型,如果是普通左孩子则为Link,如果是前驱则为Thread
    int righttype;//右孩子类型,如果是普通右孩子则为Link,如果是后继则为Thread
    struct node* left;
    struct node* right;
    int d;
}Node;

1.线索化算法

1.用一个pre指针指向访问当前节点p的前驱节点

2.在访问当前以p为根节点的子树时,如果左子树非空,则线索化左子树,获得左子树访问的最后一个节点pre;如果左子树为空,则将p的左子树类型lefttype置为Thread,p的左孩子指针置为pre。

3.处理完p的左孩子之后,判断pre的右孩子指针的类型,如果为Thread,则将pre的右孩子指针指向p

4.pre更新为p

5.如果p的右孩子指针为空,则将右孩子指针类型置为Thread;如果非空,则线索化右子树,获得右子树访问的最后一个节点pre

6.返回pre

Node* threading_btree(Node* root,Node* pre)
{
    if(!root->left)
    {
        root->lefttype=Thread;
        root->left=pre;
    }
    else
    {
        pre=threading_btree(root->left,pre);
    }
    if(pre->righttype==Thread)
        pre->right=root;
    pre=root;
    if(!root->right)
    {
        root->righttype=Thread;
    }
    else
    {
        pre=threading_btree(root->right,pre);
    }
    return pre;
}

2.线索二叉树创建

1.为了方便,我们在构建二叉树时新加了一个空头节点用于控制访问开始和结束

2.首先建立一个新的头节点thrd,让其lefttype=righttype=Thread,left和right指向本身

3.然后将其指针作为pre,根节点root作为p线索化二叉树

4.获取最后线索二叉树访问的最后一个节点pre,pre右孩子指针为Thread类型,指向thrd;thrd的左孩子指针指向pre

void create_thrdbtree(Node &thrd,Node *root)
{
    thrd.d=-1;
    thrd.lefttype=Thread;
    thrd.righttype=Thread;
    thrd.left=&thrd;
    thrd.right=&thrd;
    if(!root)
        return;
    thrd.left=threading_btree(root,&thrd);
    (thrd.left)->right=&thrd;
}

3.线索二叉树的遍历

1.设置指针p,初始值为根节点root

2.当p不等于thrd指针,如果p有左孩子,向左走到底

3.访问p节点

4.如果p的右孩子是Thread类型,则不断沿着右孩子指针也就是后继指针走,直到p的右孩子指针为Link类型p的右孩子指向thrd节点

5.p更新为p的右孩子指针

void traverse_btree2(Node *root)
{
    Node* p=root->right;
    while(p!=root)
    {
        while(p->lefttype==Link)
            p=p->left;
        cout<<p->d<<' ';
        while(p->righttype==Thread&&p->right!=root)
        {
            p=p->right;
            cout<<p->d<<' ';
        }
        p=p->right;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值