中序线索二叉树

/*一棵二叉树若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild域指示其后继.我们需要一个标志位来表示结点有没有子树,如果没有子树则将其标志设为link,否则将其标志设为thread。由于一个结点有左右孩子,故需设左右标志。

以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做线索链表,其中指向结点前驱和后继的指针,叫做线索。加上线索的二叉树称之为线索二叉树。

*/

#include <iostream>
using namespace std;
typedef char type;

//标志域的值,link表示指针,thread表示线索
typedef enum{link, thread} tag;

//二叉树的二叉线索存储表示

typedef struct bin
{
 type data;
 struct bin *lchild;  //左孩子指针
 struct bin *rchild; //右孩子指针
 tag ltag;              //左标志位
 tag rtag;             //右标志位
}bin_thr_node, *bin_thr_tree;

//定义全局变量pre来记录刚刚访问过的节点
bin_thr_tree pre;

//递归线索化二叉树

void in_threading(bin_thr_tree tree)
{
 if(tree){
  in_threading(tree->lchild);    //左子树线索化
  if(!tree->lchild){   //树的左子树为空,则指向前驱
   tree->ltag = thread;
   tree->lchild = pre;
  }
   if(!pre->rchild){   //前驱的右子树为空,则其右子树指向当前结点
   pre->rtag = thread;
   pre->rchild = tree;
  }
  pre = tree;                            //保持pre指向tree的前驱
  in_threading(tree->rchild);   //右子树线索化
 }
}

//线索化二叉树
int inorder_thr(bin_thr_tree &thr, bin_thr_tree t)
{
 thr = new bin_thr_node;
 thr->data = 0;
 thr->ltag = link;
 thr->rtag = thread;
 thr->rchild = thr;  //右孩子回指
 if(!t){             //假如t为空,则thr的左孩子回指
  thr->lchild = thr;
 }else{
  thr->lchild = t;
  pre = thr;
  in_threading(t);
  pre->rchild = thr;
  pre->rtag = thread;
  thr->rchild = pre;
 }
 return 1;
}

//先序创建二叉树.

//按先序次序输入二叉树中结点的值(一个字符), 字符'#'表示空树。

void pre_create_tree(bin_thr_tree &t)
{
 char ch;
 scanf("%c", &ch);
 if('#' == ch){
  t = NULL;
 }else{
  t = new bin_thr_node;
  t->data = ch;
  t->ltag = link;
  t->rtag = link;
  pre_create_tree(t->lchild);
  pre_create_tree(t->rchild);
 }
}

//  遍历中序线过二叉树

void in_order_traverse(bin_thr_tree t)
{
 bin_thr_tree point;
 point = t->lchild;
 while(point != t){
  while(link == point->ltag){
   point = point->lchild;
  }
  //访问最左端的孩子
  printf("%c", point->data);
  //访问后继结点
  while(thread == point->rtag && point->rchild != t){  //记住是point->rchild != t;
   point = point->rchild;
   printf("%c", point->data);
  }
  //访问最后继结点的右孩子(最后继的结点的左孩子必为其前驱,故必访问过,无需再访问)
  point = point->rchild;
 }
}

 

int main()
{
 bin_thr_tree t, thr;

//先序创建二叉树
 pre_create_tree(t);

//线索化二叉树
 inorder_thr(thr, t);

//遍历线索二叉树
 in_order_traverse(thr);
 printf("\n");
 return 0;
}
/*
测试数据:
abc##de#g##f###

测试数据的树形表示图为:

                          a
                        /   \
                       b    #
                      /  \
                     c    d                       
                    / \    / \                                       
                   #  # e   f                                       
                         / \   / \                       
                       #  g #  #                      
                          / \                 
                        #   #      

其中#表示空树(NULL)。 

*/

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值