5.3 线索二叉树

question:如何根据中序遍历序列找到一个结点的前驱

使用土办法:分配两个指针,一个根据遍历找到该结点,一个结点记录该结点的前一个结点

BiNode *p = NULL;
BiNode *pre = NULL;
BiNode *final = NULL;
void findInorder(BiTree T){
    if(T!=NULL){
       findInorder(T->lchild);
       visit(T);
       findInorder(T->rchild);
    }
}

void visit(BiNode T){
    if(p == q){
        final = pre;
    }
    else{
        pre = p;
    }
}

中序遍历线索化

思路:

首先先判断是否是叶子结点,然后根据土办法找到它的前驱和和后继,通过一个tag标签来判断它的左右子树是否是线索化

typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchlid,*rchlid;
    int ltag,rtag;
}ThreadNode,*ThreadTree;

ThreadNode *pre = NULL;

void findInorder(BiTree T){
    if(T!=NULL){
       findInorder(T->lchild);
       visit(T);
       findInorder(T->rchild);
    }
    pre->rchild = NULL;
    pre->rtag = 1;
}

void visit(ThreadNode *T){
    if(T->lchild == NULL){
        T->ltag = 1;
        T->lchild = pre;
    }
    else if(pre->lchild == NULL && pre!=NULL ){
        pre->rtag = 1;
        pre->rchild = T;
    }
    pre = T;
}

先序线索化

因为先序遍历访问顺序是:根->左->右;所以如果将左节点的next指向,pre(根节点),然后再将pre指向左节点,那么会形成回路,解决方法:

再执行线索化的时候,先判断左子树是否是线索化,如果线索化,则跳过,让该结点访问右子树


后序线索化

因为访问根节点的时候一定访问过左右子树,所以不存在回路的问题

如何根据线索化的二叉树中找前驱和后继

  1. 中序线索二叉树
    1. 如果有孩子结点,那么后继一定是右子树中最左边的结点

      代码:

      ThreadNode *findNode(ThreadNode *T){
          if(T->ltag == 1){
              return T->lchild;
          }
          else{
              return Firstnode(T->rchild);
          }
      }
      ThreadNode *Firstnode(ThreadNode *p){
          while(p->ltag == 0)
              p = p->lchild;
          return p;
      }
      
    2. 找前驱

      中序线索二叉树的前驱一定是该结点左子树的最后边的结点

      扫描二维码关注公众号,回复: 12899764 查看本文章
  2. 先序线索二叉树

    1. 找后继,先看右边是否被线索化,如果未被线索化,一定是有右孩子,如果有左孩子就访问左孩子,否则访问右节点

      ThreadNode *Firstnode(ThreadNode *p)
      {
          if(p->rtag == 1){
              return p->rchild;
          }
          else{
              if(p->ltag == 0){
                  return p->lchild;
              }
              else{
                  return p->rchild;
              }
          }
      }
      
    2. 因为顺序是根,左,右;所以如果未被线索化的结点无法找到前驱;只有三叉二叉树才有可能找到前驱

  3. 后序线索二叉树

    1. 找后序前驱:如果未被线索化,有右孩子就是前驱,无右孩子有左孩子就是前驱
    2. 如果不是三叉二叉树,无法找到后继

猜你喜欢

转载自blog.csdn.net/weixin_43771775/article/details/110941894
5.3