树和二叉树3——线索化

(保留版权,欢迎转载。请注明原始链接:http://blog.csdn.net/markcnsc/article/details/8551898)

1. 创建

typedef struct _BT {
    struct _BT *lc, *rc, *pt;
    int v;
    bool lf, rf;
} BT;

static char * nodes_param = "ABC00DE0G00F000";//"ABD000CE00F00";
static char * str = nodes_param;//creating bt
static BT* pre = NULL;//threading bt

void bt_crt (BT** p, BT* pt)
{
  char c;

  if ((c = *str++) == '0') {
    *p = NULL;
    return;
  }
  
  if (!(*p = malloc(sizeof(BT)))) {
    fprintf (stderr, "memory exhausted\n");
    exit (-1);
  }
  (*p)->v = c; (*p)->lf = (*p)->rf = 0; (*p)->pt = pt;
  bt_crt (&(*p)->lc, *p);
  bt_crt (&(*p)->rc, *p);
}

2. 线索化

void thrd_op (BT* p)
{
    if (p) return;
    if (!p->lc) {
        p->lf = 1; p->lc = pre;
    }
    if (!pre->rc) {
        pre->rf = 1; pre->rc = p;
    }
    pre = p;
}

void in_thrd_r (BT* p)
{
    in_thrd_r (p->lc);
    thrd_op (p);
    in_thrd_r (p->rc);
}

void post_thrd_r (BT* p)
{
    post_thrd_r (p->lc);
    post_thrd_r (p->rc);
    thrd_op (p);
}

void pre_thrd_r (BT* p) /*TRICKY!*/
{
    thrd_op (p);
    if (!p->lf)
        pre_thrd_r (p->lc);
    if (!p->rf)
        pre_thrd_r (p->rc);
}

BT* bt_thrd (BT* p, void(*order_func)(BT *))
{
    BT* h;
    
    if (!(h = malloc(sizeof(BT)))) {
        fprintf (stderr, "memory exhausted!\n");
        exit (-1);
    }
    h->lf = 0; h->rf = 1;
    h->lc = h->rc = h;
    
    if (p) {
        h->lc = p; pre = h;
        order_func (p);
        pre->rf = 1; pre->rc = h;
        h->rc = pre;
    }
    
    return h;
}

3. 遍历

3.1. 先序

void pre_thrd_trv (BT* h)
{
    BT* p = h->lc;
    
    while (p != h) {
        visit (p);
        p = !p->lf ? p->lc : p->rc;
    }
}

3.2. 中序

void in_thrd_trv (BT* h)
{
    BT* p = h->lc;
    
    while (p != h) {
        while (!p->lf)
            p = p->lc;
        visit (p);
        while (p->rf && p->rc != h) {
            p = p->rc;
            visit (p);
        }
        p = p->rc;
    }
}

3.3. 后序

父节点指针辅助:
void post_thrd_trv (BT* h)
{
    BT *p, *q;
    
    p = h->lc;
    while (!p->lf || !p->rf)
        p = !p->lf ? p->lc : p->rc;/*0. searching 1st node in the tree of root*/
    
    while (p != h) {
        visit (p);
        if (p->rf) {/*1-1. threaded*/
            p = p->rc;
        }
        else {/*1-2. un-threaded*/
            q = p->pt;/*turning to our parent for help*/
            if (!q) {/*1-2-1. we're root since parent is empty. exit!*/
                p = h;
            }
            else if (q->rf || p == q->rc) {
            /*1-2-2. we're right child of parent; or we're left but right child is empty*/
                p = q;
            }
            else {/*1-2-3. right child of parent is not empty*/
                p = q->rc;/*searching 1st node in the subtree of right child of parent*/
                while (!p->lf || !p->rf)
                    p = !p->lf ? p->lc : p->rc;
            }
        }
    }
}
堆栈辅助:
线索添乱,去线索;再仿后序非递归遍历。别扭:(
void post_thrd_trv (BT* h)
{
  BT* t = p;
  BT* q = NULL;
  static BT* s[N];
  int i = -1;
  bool f;
	
  f = p->lf; p = p->lc;
  while (!f || i >= 0) {
    if (!f) {
      s[++ i] = p;
      f = p->lf;
      p = p->lc;
    }
    else {
      p = s[i];
      if (p->rf || p->rc == q) {
        i --;
        visit (p);
        q = p;
        p = t;
      }
      else {
        f = p->rf;
        p = p->rc;
      }
    }
  }
}

4. 实例

int main (int argc, char** argv)
{
  BT *p, *h;

  bt_crt (&p, NULL);
  h = bt_thrd (p, in_thrd_r);
  in_thrd_trv (h);
  /*h = bt_thrd (p, post_thrd_r);
    post_thrd_trv (h);*/
  /*h = bt_thrd (p, pre_thrd_r);
    pre_thrd_trv (h);*/
  
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值