线索二叉树

简介: 线索二叉树-概念          当用二叉链表作为二叉树的存储结构时,因为每个结点中只有指向其左、右儿子结点的指针,所以从任一结点出发只能直接找到该结点的左、右儿子。

             

线索二叉树-概念

   

     当用二叉链表作为二叉树的存储结构时,因为每个结点中只有指向其左、右儿子结点的指针,所以从任一结点出发只能直接找到该结点的左、右儿子。在一般情况下靠它无法直接找到该结点在某种遍历序下的前驱和后继结点。如果在每个结点中增加指向其前驱和后继结点的指针,将降低存储空间的效率。

我们可以证明:在n个结点的二叉链表中含有n+1个空指针。因为含n个结点的二叉链表中含有个指针,除了根结点,每个结点都有一个从父结点指向该结点的指针,因此一共使用了n-1个指针,所以在n个结点的二叉链表中含有n+1个空指针。

因此可以利用这些空指针,存放指向结点在某种遍历次序下的前驱和后继结点的指针。这种附加的指针称为线索,加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(ThreadedBinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。

实现

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef char DataType;/*¶¨ÒåDataTypeÀàÐÍ*/
typedef enum {Link,Thread}PointerTag;
typedef struct node{
  DataType data;
  struct node *lchild, *rchild;/*×óÓÒº¢×Ó×ÓÊ÷*/
  PointerTag LTag,RTag;
}BiThrNode;
typedef BiThrNode *BiThrTree ;
void  CreatBinTree(BiThrTree *T)
{ /*¹¹Ôì¶þ²æÁ´±í,×¢Òâ:ÊäÈëÐòÁÐÊÇÏÈÐòÐòÁÐ*/
 char ch;
 if ((ch=getchar())==' ')
  *T=NULL;
 else{ /*¶ÁÈë·Ç¿Õ¸ñ*/
  *T=(BiThrNode *)malloc(sizeof(BiThrNode));/*Éú³É½áµã*/
 (*T)->data=ch;(*T)->LTag=Link;(*T)->RTag=Link;
 CreatBinTree(&(*T)->lchild); /*¹¹Ôì×ó×ÓÊ÷    */
 CreatBinTree(&(*T)->rchild); /*¹¹ÔìÓÒ×ÓÊ÷*/
 }
}

BiThrTree pre;
void InThreading(BiThrTree p)
{
  if(p)
  {InThreading(p->lchild);/*×ó×ÓÊ÷ÏßË÷»¯*/
  if(!p->lchild){p->LTag=Thread;p->lchild=pre;}/*Ç°ÇýÏßË÷*/
  if(!pre->rchild){pre->RTag=Thread;pre->rchild=p;}/*ºó¼ÌÏßË÷*/
  pre=p;/*±£³ÖpreÖ¸Ïòp*/
  InThreading(p->rchild);/*ÓÒ×ÓÊ÷ÏßË÷»¯*/
 }
}
int InOrderThreading(BiThrTree *Thrt,BiThrTree T)
                                  /*ÖÐÐò±éÀ÷¶þ²æÊ÷T£¬²¢½«ÆäÖÐÐòÏßË÷»¯£¬ThrtÖ¸ÏòÍ·½áµã*/
{ if(!(*Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) exit(0);
  (*Thrt)->LTag=Link;(*Thrt)->RTag=Thread;/*½¨Í·½áµã*/
  (*Thrt)->rchild=*Thrt;/*ÓÒÖ¸Õë»ØÖ¸*/
  if(!T) (*Thrt)->lchild=*Thrt;
  else
  { (*Thrt)->lchild=T;pre=*Thrt;
    InThreading(T);/*ÖÐÐò±éÀú½øÐÐÖÐÐòÏßË÷»¯*/
 pre->rchild=*Thrt;pre->RTag=Thread;/*×îºóÒ»¸ö½áµãÏßË÷»¯*/
 (*Thrt)->rchild=pre;
  }
  return 1;
}

int print(BiThrTree e)
{printf("%d  %c  %d\n",e->LTag,e->data,e->RTag);return 1;}

int InOrderTraverse(BiThrTree T,int (* visit)(BiThrTree e))
                                  /*中序遍历线索二叉树*/
{BiThrTree p;
 p=T->lchild;/*pÖ¸Ïò¸ù½áµã*/
 while(p!=T)/*空树或线索遍历结束时p==T*/
 {while(p->LTag==Link) p=p->lchild;
  if(!visit(p)) return 0;/*´òÓ¡*/
  while(p->RTag==Thread&&p->rchild!=T)
  {p=p->rchild;visit(p);}/*·ÃÎʺó¼Ì½áµã*/
  p=p->rchild;
 }
 return 1;
}

void main()
{ /*测试程序*/
  BiThrTree T,Thrt;
  CreatBinTree(&T);
  InOrderThreading(&Thrt,T);
  InOrderTraverse(Thrt,print);
  getch();
}
/*可以输入"-+a  *b  -c  d  /e  f  "*/

相关文章
|
21天前
|
Python
二叉树前中后序遍历
这段内容是关于二叉树的前序、中序和后序遍历的Python实现。`Solution`类包含三个方法:`preorderTraversal`、`inorderTraversal`和`postorderTraversal`,分别返回二叉树节点值的前序、中序和后序遍历列表。每个方法都是递归的,遍历顺序为:前序(根-左-右)、中序(左-根-右)、后序(左-右-根)。
14 4
|
3月前
|
算法
带你深入理解二叉树的遍历
带你深入理解二叉树的遍历
|
8月前
|
存储
线索化二叉树
线索化二叉树
36 0
二叉树的前序、中序和后序遍历
二叉树的前序、中序和后序遍历
|
JavaScript 前端开发 Java
二叉树的先序、中序、后序遍历
二叉树的先序、中序、后序遍历
106 0
二叉树的先序、中序、后序遍历
|
存储 Java
线索二叉树
线索二叉树在二叉树的结点上加上线索的二叉树称为线索二叉树。
104 0
先序、中序、后序遍历确定唯一树
快速学习先序、中序、后序遍历确定唯一树
先序、中序、后序遍历确定唯一树
【C++】二叉树的遍历:前序、中序、后序、层序
【C++】二叉树的遍历:前序、中序、后序、层序
【C++】二叉树的遍历:前序、中序、后序、层序
【小白学算法】8.二叉树的遍历,前序、中序和后序
【小白学算法】8.二叉树的遍历,前序、中序和后序
【小白学算法】8.二叉树的遍历,前序、中序和后序

热门文章

最新文章