从0开始学习数据结构-树与二叉树-线索二叉树①

209 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

线索二叉树

这些指向直接前驱结点和直接后继结点的指针被称为线索(thread),加了线索的二叉树被称为线索二叉树。

线索二叉树的构造

一个具有n个结点的二叉树若采用二叉链表存储结构,在2n个指针域中只有n-1个指针域是用来指向结点的孩子,而另外n+1个指针域存放的都是空值(NULL)。为此,可以利用某结点空的左指针域(Ichild)指出该结点在某种遍历序列中的直接前驱结点的位置,利用结点空的右指针域(rchild)指出该结点在某种遍历序列中的直接后继结点的位置,对于那些非空的指针域,则仍然存放指向该结点左、右孩子的指针。这样,就得到了一棵线索二叉树

由于遍历序列可由不同的遍历方法得到,因此,线索树可以有前序线索二叉树、中序线索二叉树和后序线索二叉树之分。把二叉树改造成为线索二叉树的过程称为线索化。

image.png

区别某个结点的指针域内存放的是指针还是线索:

1.每个链结点增设两个标志位域lbit和 rbit,则有

image.png

当链结点中增加了两个标志域以后,链结点的构造如图7.25所示。

image.png

2.不改变链结点的构造,仅在作为线索的地址前面加一个负号,即负的地址表示线索,正的地址表示指针。

这两种区别线索与指针的方法各有利弊。前者与后者相比,增加了存储空间的开销,但在对线索二叉树的操作过程中,对地址的处理要简单。

从图7.24可以看到,还有少数几个结点的线索仍然悬空,为此,解决的方法是设置一个头结点,其存储地址记为HEAD,数据域可以不存放信息﹐只是令其左指针域指向二叉树的根结点,右指针域指向自己。这样,二叉树中所有尚无“去处”的线索都指向头结点。经过如此处理,可以使在后面讨论的算法(在线索二叉树中查找某结点的直接前驱结点和直接后继结点的算法)中不必再判断线索是否为空的情况。以图7.24(b)所示的中序线索二叉树为例,其二叉链表如图7.26 所示。这里,是采用第①种方法来区别指针与线索的。

image.png

在C语言中,可以按如下方法来定义线索二叉树的二叉链表结构的类型(采用第①种方法区分指针与线索)。

typedef struct node{
    datatype data;
    struct node1 *lchild,*rchild;
    int lbit,rbit;
} TBTNode , *TBTREE;