程序实现线索二叉树的结构及其操作

#define MAXSIZE 100
#include <stdlib.h>
#include <stdio.h>

typedef char DATA;

typedef enum
{
	SubTree,
	Thread
}NodeFlag;

typedef struct ThreadTree
{
	DATA data;
	NodeFlag lflag;
	NodeFlag rflag;
	struct ThreadTree *left;
	struct ThreadTree *right;
}ThreadBinTree;

ThreadBinTree * Previous = NULL;
/************************************************************************ 
函数名称:BinTreeThreading_LDR 
函数功能:对二叉树进行中序线索化 
函数参数:bt为结点指针
函数返回:无
************************************************************************/ 
void BinTreeThreading_LDR(ThreadBinTree *bt)
{
	if (bt)
	{
		//递归调用,将左子树线索化
		BinTreeThreading_LDR(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_LDR(bt->right);
	}	
}

/*************************************************************************************
查找后继结点:
在中序线索二叉树中,查找结点p的中序后继结点分两种情况:
1:若结点p的右子树为空(即p->rflag == Thread),则p->right为右线索,直接指向p的中序后继。
2:若结点p的右子树不为空(即p->rflag == SubTree),则p的中序后继必是其右子树中第一个中序
遍历到的结点。
**************************************************************************************/
/************************************************************************ 
函数名称:BinTreeNext_LDR 
函数功能:对二叉树进行中序线索化之后查找后继结点 
函数参数:bt为结点指针
函数返回:bt的后继结点的指针
************************************************************************/ 
ThreadBinTree *BinTreeNext_LDR(ThreadBinTree *bt)
{
	ThreadBinTree * nextnode;
	if (!bt) return NULL;
	if (bt->rflag == Thread)
		return bt->right;
	else
	{
		nextnode = bt->right;
		while (nextnode->lflag == SubTree)
			nextnode = nextnode->left;
		return nextnode;
	}
	return NULL;
}
/*************************************************************************************
查找前驱结点:
在中序线索二叉树中,查找结点p的中序前驱结点分两种情况:
1:若结点p的左子树为空(即p->lflag == Thread),则p->left为左线索,直接指向p的中序前驱。
2:若结点p的左子树不为空(即p->lflag == SubTree),则从p的左子树出发,沿该子树的右指针链
往下查找,直到找到一个没有右子树的结点为止。
**************************************************************************************/
/************************************************************************ 
函数名称:BinTreePrevious_LDR 
函数功能:对二叉树进行中序线索化之后查找前驱结点 
函数参数:bt为结点指针
函数返回:bt的前驱结点的指针
************************************************************************/ 
ThreadBinTree *BinTreePrevious_LDR(ThreadBinTree *bt)
{
	ThreadBinTree * prenode;
	if (!bt) return NULL;
	if (bt->lflag == Thread)
		return bt->left;
	else
	{
		prenode = bt->left;
		while (prenode->lflag == SubTree)
			prenode = prenode->right;
		return prenode;
	}
}
/************************************************************************ 
函数名称:oper 
函数功能:输出该结点的数据
函数参数:p为结点指针
函数返回:无
************************************************************************/ 
void oper(ThreadBinTree *p)
{
	printf("%c ", p->data);
	return;
}
/************************************************************************ 
函数名称:ThreadBinTree_LDR 
函数功能:对二叉树进行中序遍历
函数参数:bt为结点指针
函数返回:无
************************************************************************/ 
void ThreadBinTree_LDR(ThreadBinTree *bt, void (* oper)(ThreadBinTree *p))
{
	if (bt)
	{
		while (bt->lflag == SubTree)//有左子树
			bt = bt->left;//找最左下结点,即中序序列的开始结点
		do
		{
			oper(bt);
			bt = BinTreeNext_LDR(bt);//找中序后继结点
		}while(bt);
	}
}
/************************************************************************ 
函数名称:ThreadBinTree_LDR 
函数功能:对二叉树进行中序遍历
函数参数:bt为结点指针
函数返回:无
************************************************************************/ 
ThreadBinTree * InitRoot()
{
	ThreadBinTree *node;
	if (node = (ThreadBinTree *)malloc(sizeof(ThreadBinTree)))
	{
		printf("\n输入根结点数据:");
		//scanf("%s", &node->data);
		node->data = getchar();
		node->left = NULL;
		node->right = NULL;
		return node; 
	}
}
/************************************************************************ 
函数名称:BinTreeAddNode 
函数功能:添加结点到二叉树 
函数参数:bt为父结点,node为子结点,n=1表示添加左子树,n=2表示添加右子树 
函数返回:成功返回1,失败返回0 
************************************************************************/  
int BinTreeAddNode(ThreadBinTree *bt, ThreadBinTree *node, int n)  
{  
    if (bt == NULL)  
    {  
        printf("父结点不存在,请先设置父结点!\n");  
        return 0;  
    }  
    switch(n)  
    {  
    case 1: //添加到左结点  
        if (bt->left)  
        {  
            printf("左子树不为空!\n");  
            return 0;  
        }  
        else  
            bt->left = node;  
        break;  
    case 2://添加到右结点  
        if (bt->right)  
        {  
            printf("右子树不为空!\n");  
            return 0;  
        }  
        else  
            bt->right = node;  
        break;  
    default:  
        printf("输入错误!\n");  
        return 0;  
    }  
    return 1;  
}
/************************************************************************ 
函数名称:BinTreeFind 
函数功能:在树中查找某个数值等于data的结点 
函数参数:bt为父结点, 数值为data 
函数返回:若没有找到返回NULL,若找到返回该结点的指针 
************************************************************************/  
ThreadBinTree *BinTreeFind(ThreadBinTree *bt, DATA data)  
{  
    ThreadBinTree *p;  
  
    if (bt == NULL)  
        return NULL;  
    else  
    {  
        if (bt->data == data)  
            return bt;  
        else  
        {  
            if (p = BinTreeFind(bt->left, data))  
                return p;  
            else if (p = BinTreeFind(bt->right, data))  
                return p;  
            else  
                return NULL;  
        }  
    }  
}  
/************************************************************************ 
函数名称:AddNode 
函数功能:添加结点到二叉树 
函数参数:bt为父结点 
函数返回:成功返回1,失败返回0 
************************************************************************/  
void AddNode(ThreadBinTree *bt)
{
	ThreadBinTree * node, *parent;  
    DATA data;  
    char select;  
    if (node = (ThreadBinTree *)malloc(sizeof(ThreadBinTree)))  
    {  
        printf("\n输入二叉树结点数据:");  
        fflush(stdin);//清空输入缓冲区  
     //   scanf("%c", &node->data);  
        node->data = getchar();
		node->left = NULL;  
        node->right = NULL;  
        printf("输入父结点数据:");  
        fflush(stdin);  
     //   scanf("%c", &data); 
		data = getchar();
        parent = BinTreeFind(bt, data);  
        if (!parent)  
        {  
            printf("未找到父结点!\n");  
            free(node);  
            return;  
        }  
        printf("1.添加到左子树\n2.添加到右子树\n");  
        do  
        {  
            select = getchar();  
            select = select - '0';  
            if (select == 1 || select == 2)  
                BinTreeAddNode(parent, node, select);  
        }while(select != 1 && select != 2);  
  
    }  
    return;  
}
/************************************************************************ 
函数名称:BinTreeClear 
函数功能:清空二叉树,释放每个结点的内存,使树变为空树 
函数参数:bt为父结点 
函数返回:没有返回值 
************************************************************************/  
void BinTreeClear(ThreadBinTree *bt)  
{  
    if (bt)  
    {  
        BinTreeClear(bt->left);  
        BinTreeClear(bt->right);  
        free(bt);  
        bt = NULL;  
    }  
    return;  
}  
 
/************************************************************************ 
函数名称:main 
函数功能:主函数
函数参数:无 
函数返回:成功返回0 
************************************************************************/ 
int main()
{
	ThreadBinTree *root = NULL;
	char select;
	 do  
    {  
        system("cls");  
        printf("1.设置二叉树根元素       2.添加二叉树结点\n");  
        printf("3.生成中序线索二叉树     4.遍历线索二叉树\n");  
        printf("0.退出\n");  
          
        select = getchar();  
        getchar();  
        switch(select)  
        {  
        case '1':             
            root = InitRoot();  
            getchar();  
            getchar();  
            break;  
        case '2':  
            AddNode(root);  
            getchar();  
            break;  
        case '3':  
            BinTreeThreading_LDR(root);  
			printf("\n生成中序线索二叉树完毕!\n"); 
            getchar();  
            break;  
        case '4':  
            printf("\n中序线索二叉树遍历的结果:");  
            ThreadBinTree_LDR(root, oper);  
            printf("\n");  
            getchar();  
            break;  
        case '0':  
            break;  
        default:  
            break;  
        }  
    }while(select != '0');  
    BinTreeClear(root);  
    root = NULL;  
    getchar();  
    getchar();  
    return 0;  
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值