用C语言实现线索二叉树

 

 

前言

为什么会有线索二叉树?当以二叉链表形式来保存二叉树时,只能找到节点的左右子树信息,而不能直接得到节点的前驱和后继信息(只有通过遍历,在动态过程中才能查到前驱和后继的信息)

因此就有了线索二叉树,由二叉树的性质可知,一棵具有 n 个节点的二叉树,对应的二叉链表中共有 2n 个指针域,其中 n-1 个用于指向除根节点以外的 n-1 个节点,另外n+1个指针域为空。可以利用二叉链表中的这些空指针域来存放节点的前驱和后继,即可找到线索二叉树。

 

 

线索二叉树的创建

 

用C语言实现线索二叉树_第1张图片

 

 

代码实现

#include
#include
#include 

typedef char DATE;
typedef enum
{
   subtree,
   thread
}nodeflag;

typedef struct threadtree
{
	DATE date;
    nodeflag lflag;
	nodeflag rflag;
	struct threadtree *left;
	struct threadtree *right;	
}threadbintree;
threadbintree *previous=NULL;


//设置根节点 
threadbintree *threadbininit()
{
   threadbintree *bt;
   if(bt=(threadbintree *)malloc(sizeof(threadbintree)))
   {
   	    printf("根节点为:"); 
   	    scanf("%s",&bt->date); //%s
   	    bt->left=NULL;
   	    bt->right=NULL;
   	    return bt;
   }
   return NULL;

}

//二叉树的清空
void bintreeclear(threadbintree *q)
{
    if(q)
    {
	    bintreeclear(q->left);
		bintreeclear(q->right);
	    free(q);
		q=NULL;	 
	}
    return;
} 

//查找父节点
threadbintree *searchnode(threadbintree *bt,DATE date)
{
	threadbintree *p;
    if(bt==NULL)
    {
	    return NULL; 
	} 
    else
    {
	    if(bt->date==date)
	    {
		   return bt;
		}
	    else
	    {
		    if(p=searchnode(bt->left,date))
		         return p;
		         
		    else if(p=searchnode(bt->right,date))
		         return p;
		         
		    else 
                  return NULL;
        }
    }
} 

//添加到左或者右
int bintreeaddnode(threadbintree *bt,threadbintree *q,int n)
{
	if(bt==NULL)
	{
	   printf("该父节点不存在"); 
	   return 0;
	}
    switch(n)
	{
	    case 1:
	    	if(bt->left)
	    	{
	    		printf("该左结点已有值\n");
	    		return 0; 
	    	}
	        bt->left=q;
	        printf("添加成功\n");
	        break;
	    case 2:
	    	if(bt->right)
			{
			    printf("该右节点已有值"); 
			    return 0;    
			} 
	        bt->right=q;
	         printf("添加成功\n");
	        break;
	} 
    return 1;
} 

//添加节点
void addnode(threadbintree *bt)
{
	 int select;
     threadbintree *parent,*node;
     DATE date;
     if(node=(threadbintree *)malloc(sizeof(threadbintree))) 
    { 
	     printf("输入添加的数据:");
         fflush(stdin);
	      scanf("%s",&node->date);//
     	 node->left=NULL;
	     node->right=NULL;
    	 printf("输入要添加的父节点:");
	     fflush(stdin);
    	 scanf("%s",&date);//
    	 parent=searchnode(bt,date);
    	 if(parent==NULL)
	     {
	        printf("该节点不存在");
	    	free(node);
	    	return ;
         }
     
         printf("select:1.添加左边  2.添加右边\n");
         do{
	      select=getch();
	      select-='0';
	      if(select==1||select==2)
		  {
		     bintreeaddnode(parent,node,select);
		  }   
	   }while(select!=1&&select!=2);
    }
    return ;   
}


//生成线索二叉树 
void bintreethreading(threadbintree *bt)
{
    if(bt)
    {
         bintreethreading(bt->left);
		 bt->lflag=(bt->left)?subtree:thread;
		 bt->rflag=(bt->right)?subtree:thread;       	
         if(previous)
		 {
		     if(previous->rflag==thread)
			     previous->right=bt;
			 if(bt->lflag==thread)
			     bt->left=previous;   
	 	 }
	 	 previous=bt;
	 	 bintreethreading(bt->right);
    }
}

void oper(threadbintree *bt)
{
    printf("%c ",bt->date);
    return; 

}


//查找后继 
threadbintree *threadbintreenext(threadbintree *bt)
{
	threadbintree *node; 
	if(!bt)  return NULL;
    if(bt->rflag==thread)
	  return bt->right;
	else
	{  
	     node=bt->right;
	     while(node->lflag==subtree)
	           node=node->left;
            
         return node;
    }
} 

//中序遍历线索二叉树
void threadbintreezhong(threadbintree *bt,void(*oper)(threadbintree *bt))
{
	
	if(bt)
	{
        while(bt->lflag==subtree) 
             bt=bt->left;
        do{
		    oper(bt);
   		    bt=threadbintreenext(bt);
		}while(bt);     
    }

} 


int main()
{
   int select;
   threadbintree *bt=NULL;
   void (*oper1)();
   oper1=oper;
   while(1)
   {
       printf("\t\t1.设置根节点\n");
       printf("\t\t2.添加节点\n");
	   printf("\t\t3.生成中序线索二叉树\n");
	   printf("\t\t4.遍历中序二叉树\n");
	   printf("\t\t0.退出\n");
	   printf("select:");
	   scanf("%d",&select);
	   switch(select)
	   {
	        case 1: 
	              bt=threadbininit();
	              break;
	        case 2:
	       	      addnode(bt);
	       	      break;
	        case 3:
				  bintreethreading(bt);
				  break;
		    case 4:
			      threadbintreezhong(bt,oper1);
			      break;
		    case 5:
		    	break;
	   } 
    }
    bintreeclear(bt);
    bt=NULL;
    return 0;
}
	

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(用C语言实现线索二叉树)