树——线索二叉树的建立、遍历(前序、中序、后序)

      直接上代码。
      
#include<iostream>
#include<cstdio>
using namespace std;

#define OK 1
#define ERROR 0

typedef int Status;
typedef char TElemType;
/*
  定义线索二叉树的数据结构
*/
typedef struct BiThrNode
{
	char data;//结点对应的数据
	int ltag, rtag;//左右孩子标记
	struct BiThrNode *lchild;//左孩子
	struct BiThrNode *rchild;//右孩子
}BiThrNode,*BiThrTree;
/*
   输出对应结点里面的值
*/
Status PrintElement(TElemType e)
{
	cout << e;
	return OK;
}


/*
寻找p结点在Thrt树中的父节点,便于进行后序遍历
*/
BiThrTree parent(BiThrTree &Thrt, BiThrTree &p)
{
	BiThrTree temp=Thrt->lchild;

	if (p==Thrt->lchild)//p即为根节点,返回创建的头结点
	{
		return Thrt;
	}
	if (temp->lchild == p)
	{
		return temp;//父节点就是我们寻找的结点
	}
	else
	{
		temp = temp->lchild;
		while (temp->lchild != p&&temp->rchild != p)
		{
			/*
			如果节点有右孩子,那就往右
			如果节点没有右孩子,就往左
			没有左孩子,就往前驱
			*/
			if (temp->rtag == 0)
			{
				temp = temp->rchild;
			}
			else
			{
				temp = temp->lchild;
			}
		}
		return temp;
	}
}



/*
    创建线索二叉树,初始化跟二叉树的初始化递归算法一样
*/
Status CreateBiThrTree(BiThrTree &T)
{
	char ch;
	cin >> ch;
	if (ch == '#')
		T = NULL;
	else
	{
		if (!(T = (BiThrNode *)malloc(sizeof(BiThrNode))))
			exit(OVERFLOW);

		T->data = ch;
		T->ltag = 0;
		T->rtag = 0;
		CreateBiThrTree(T->lchild);
		CreateBiThrTree(T->rchild);
	}
	return OK;
}

/*
    T指向头结点,头结点的左链lchild指向根节点
	中序遍历二叉线索树T的非递归算法,对每个数据元素调用函数Visit

*/
Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
	BiThrTree p = T->lchild;
	while (p&&(p != T))
	{
		while (p->ltag == 0)
		{			
			p = p->lchild;
		}
		Visit(p->data);
		while (p->rtag == 1 && p->rchild != T)
		{
			p = p->rchild;
			Visit(p->data);
		}
		p = p->rchild;
	}
	return OK;
}
/*
   前序遍历二叉树非递归算法(仿造中序遍历)
*/
Status PreOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
	BiThrTree p = T;
	while (p)
	{
		while (p->ltag == 0)
		{
			Visit(p->data);
			p = p->lchild;
		}		
		Visit(p->data);
		p = p->rchild;
	}
	return OK;
}
/*
   后序遍历二叉树非递归算法
*/
Status PostOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
	BiThrTree p = T->lchild;
	BiThrTree pre = T;

	//p指向第一个被访问结点
	while (p->ltag == 0||p->rtag==0)
	{
		while(p->ltag==0)
			p = p->lchild;
		if (p->rtag == 0)
			p = p->rchild;
	}
	while (p != T) 
	{
		Visit(p->data);
		pre = parent(T, p);//找到该节点的双亲

		if (T == pre)//如果双亲是T,就说明p是根节点,无后继
		{
			p = T;
		}
		//如果p是双亲的右孩子,或者双亲无右孩子,则后继为双亲
		else if(p==pre->rchild||pre->rtag==1)
		{
			p = pre;
		}
		else
		{
			//若p的双亲有右孩子,后继为双亲右子树上后序遍历的第一个孩子
			while (pre->rtag == 0)
			{
				pre = pre->rchild;
				while (pre->ltag == 0)
				{
					pre = pre->lchild;
				}
			}
			p = pre;
		}
	}
	
		
	
	
	return OK;
}
/*
  中序遍历进行二叉树线索化
*/
void InThreading(BiThrTree p,BiThrTree &pre)
{
	if (p)
	{
		InThreading(p->lchild,pre);//左子树线索化
		if (!p->lchild)
		{
			p->ltag = 1;
			p->lchild = pre;
		}
		if ((!pre->rchild)&&pre->rchild==NULL)
		{
			pre->rtag = 1;
			pre->rchild = p;
		}
		pre = p;
		InThreading(p->rchild, pre);//右子树线索化
	}
}
/*
   前序遍历进行二叉树线索化
*/
void preThreading(BiThrTree p, BiThrTree &pre)
{
	if (p)
	{
		if (p->lchild == NULL)
		{
			p->lchild = pre;
			p->ltag = 1;
		}
		if (pre != NULL&&pre->rchild == NULL)
		{
			pre->rchild = p;
			pre->rtag = 1;
		}
		pre = p;
		if (p->ltag == 0)
			preThreading(p->lchild, pre);
		if (p->rtag == 0)
			preThreading(p->rchild, pre);
	}
}

/*
   后序遍历进行线索二叉树化
*/
void postThreading(BiThrTree p, BiThrTree &pre)
{
	if (p)
	{
	postThreading(p->lchild, pre);
	postThreading(p->rchild, pre);
	if (p->lchild==NULL)
	{
		p->lchild = pre;
		p->ltag = 1;
	}
	if (pre != NULL&&pre->rchild == NULL)
	{
		pre->rchild = p;
		pre->rtag = 1;
	}
	pre = p;
   }
}


/*
   中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
*/
Status InOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
	//建立头结点
	if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
		exit(OVERFLOW);
	Thrt->ltag = 0;
	Thrt->rtag = 1;

	Thrt->rchild = Thrt;//右指针回指
	BiThrTree pre;
	if (!T)
		Thrt->lchild = Thrt;//若二叉树为空,则指针回指
	else
	{
		Thrt->lchild = T;
		pre = Thrt;
		InThreading(T,pre);//中序遍历进行中序线索化
		pre->rchild = Thrt;//最后一个结点线索化
		pre->rtag = 1;
		Thrt->rchild = pre;
	}
	return OK;
}

/*
   后序遍历二叉树,并将其线索化,原理同中序
*/
Status PostOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
	//建立头结点
	if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
		exit(OVERFLOW);
	Thrt->ltag = 0;
	Thrt->rtag = 1;

	Thrt->rchild = Thrt;//右指针回指
	BiThrTree pre;

	if (!T)
		Thrt->lchild = Thrt;//若二叉树为空,则指针回指
	else
	{
		Thrt->lchild = T;
		pre = NULL;
		postThreading(T, pre);//后序遍历进行后序线索化
		pre->rchild = Thrt;
		pre->rtag = 1;
		Thrt->rchild = pre;//最后一个结点线索化
	}
	return OK;
}



void main()
{
	
	BiThrTree T1, Thrt1;
	cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
	CreateBiThrTree(T1);
	if (InOrderThreading(Thrt1, T1) == OK)
		cout << "成功建立中序线索化链表!\n";
	cout << "中序遍历线索二叉树,结果是:\n";
	InOrderTraverse_Thr(Thrt1, PrintElement);
	cout << endl;

	BiThrTree T2;
	 
	cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
	CreateBiThrTree(T2);
	BiThrTree test1 = T2;
	preThreading(T2, test1);
	cout << "前序遍历线索二叉树,结果是:\n";
	PreOrderTraverse_Thr(T2, PrintElement);
	cout << endl;
	
	BiThrTree T3,Thrt3;
	cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
	CreateBiThrTree(T3);
	if (PostOrderThreading(Thrt3, T3) == OK)
		cout << "成功建立后序序线索化链表!\n";
	cout << "后序遍历线索二叉树,结果是:\n";
	PostOrderTraverse_Thr(Thrt3, PrintElement);
	cout << endl;

	system("pause");
}

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值