6.5.3 线索链表的生成

  现在的问题是如何建立二叉树的线索链表?

  由于线索链表上保存的是"遍历"过程中得到的前驱和后继的信息,显然,线索链表应该在遍历过程中建立,即在遍历过程中改变二叉链表中结点的"空指针"以及相应的"指针类型标志"。若结点没有左子树,则令其左指针指向它的"前驱"并将左指针类型标志改为"Thread",若结点没有右子树,则令它的右指针指向它的"后继"并将右指针类型标志改为"Thread"。为了获取"前驱"的信息,需要在遍历过程中添加一个指向其前驱的指针 pre。

  由此建立线索链表的过程即为将遍历过程中对结点进行下列"访问"操作( 指针 p 指向当前访问的结点,pre 指向在它之前"刚刚"访问过的结点):
算法
  if (!pre->Rchild) {
   pre->RTag = Thread;
   pre->Rchild = p;
  }
  if (!p->Lchild) {
   p->LTag = Thread;
   p->Lchild = pre;
  }
  pre = p;
   
 
 这里的前驱指针 pre 和当前指针 p 的关系类似于线性链表中的前驱和后继,只是在线性链表中两者之间仅存在着简单关系"p=pre->next",而在此 p 既不简单地是 pre->Lchild,也不是 pre->Rchild,它们之间的关系取决于遍历过程。

  假设p指向当前访问的结点,则在访问结束继续进行左子树或右子树的遍历之前,令"pre=p"。则当 p 对遍历过程中的下一个结点进行访问时,pre 所指即为 p 所指结点的前驱,反之,p 所指结点为 pre 所指结点的后继。

  也可将左窗口中所列操作视作遍历算法中的函数参数 Visit 的实体。