中序线索二叉树

 对于一颗有n个节点的二叉树,每个节点有2个指针域,共2n个指针域,使用n-1个指针域,二叉线索树便是将剩下的n+1个指针域也利用起来。

在普通二叉树中,我们仅知道一个节点的左右孩子,并不知道它的直接前驱节点和直接后驱节点,若能知道它的前驱节点和后去节,便可以将这个数据结构进行遍历,可极大的提高效率。

二叉线索树节点结构:

 

lchid  lflag data rchild rflag

当lflag=0时,lchild指向左孩子,为1时lchild指向前驱节点

当rflag=0时,rchild指向右孩子,为1时rchild指向后继节点

结构定义:

struct node
{
    char a;
    struct node* lc, * rc;
    int lflag, rflag;
};

 

线索化规则:对于一个节点,当它的lflag=1时lchild指向前驱节点,当rflag=1时rchild指向后继节点。所以我们需要一个指针p指向当前节点,pre指向p节点的前驱节点。若p节点的lflag=1,p的lchild指向pre,

若pre的rflag=1,pre的rchild指向p。

  • 线索化:
void intread(struct node* p, struct node* pre)
{
    if (p)
    {
        intread(p->lc, pre);//不断访问左子树,直到叶节点
        if (!p->lc)
        {
            p->lflag = 1;
            p->lc = pre;
        }
        if (pre && !pre->rc)
        {
            pre->rflag = 1;
            pre->rc = p;
        }
        pre = p;//不断跟新pre,使pre始终为p的前驱节点
        intread(p->rc, pre);//访问右子树
    }
}

 

  • 遍历线索二叉树
struct node* first(struct node* p)
{
    while (p->lflag==0) p = p->lc;//不断遍历直到p为该子树的最左子树
    return p;
}
struct node* next(struct node* p)
{
    if (p->rflag == 0) return first(p->rc);//如果rflag=0,改点有右孩子,那就返回右孩子的最左子树
    else return p->rc;//返回后继节点
}
void throughout(struct node* root)
{
    for (struct node* p = first(root); p; p = next(p))
    {//对节点的操作
        cout << p->a << " ";
    }
}

原地址:https://www.cnblogs.com/leonandyou/p/11296746.html

posted @ 2020-05-14 10:20  yin101  阅读(910)  评论(0)    收藏  举报