数据结构5.1.1 - 线索二叉树 代码测试

1 代码

#include<bits/stdc++.h> 
#define max 1000
#define num 100
using namespace std;

typedef struct TBNode
{
	int data; //数据 
	int ltag, rtag; 
	// 0,1;
	// ltag = 0, lchild指向孩子-左子树;  ltag = 1, lchild指向前驱
	// rtag = 0, rchild指向孩子-右子树;  rtag = 1, rchild指向后继
	struct TBNode *lchild, *rchild; // 左子树、右子树 指针 
}*TBLink, TBNode;

void creat(); // 生成树 大纲 函数 
void creat0(TBLink &L); // 生成树结点,未线索化 
void creatTree(TBLink &L, int &n, int length); // 跟 creat0() 

void creat1(TBLink &L); // 前序线索化 
void precreat(TBLink &L, TBLink &pre); // 跟 creat1() 前序线索化
void preorder(TBLink L); // 前序遍历递归
void preorder3(TBLink L); // 前序遍历

void creat2(TBLink &L); // 中序化 
void increat(TBLink &L, TBLink &pre); // 跟 creat2() 中序线索化 
void inorder(TBLink L); // 中序遍历递归 
void inorder3(TBLink L); // 中序遍历  
TBLink next(TBLink L);
TBLink first(TBLink L);

void creat3(TBLink &L); // 后序化 
void postcreat(TBLink &L, TBLink &pre); // 跟 creat2() 中序线索化 
void postorder(TBLink L); // 后序遍历递归 
void postorder3(TBLink L); // 后序遍历  

int main()
{
	srand(time(NULL));
	creat();
	
	
	system("pause");
	return 0;
}

void creat()
{
	TBLink L;
	
	L = (TBNode *)calloc(1, sizeof(TBNode));
	creat0(L); // 生成树 
	creat1(L); // 前序化 
	cout << "前序遍历 - 递归:" << endl; 
	preorder(L); // 前序遍历 - 递归
	cout << endl << endl;
	cout << "中序遍历 - 递归:" << endl; 
	inorder(L); // 中序遍历 - 递归 
	cout << endl << endl;
	cout << "后序遍历 - 递归:" << endl; 
	postorder(L); // 后序遍历 - 递归
	cout << endl << endl; 
	cout << "前序遍历:" << endl; 
	preorder3(L);
	cout << endl << endl; 

	L = (TBNode *)calloc(1, sizeof(TBNode));
	creat0(L); // 生成树
	creat2(L); // 中序化
	cout << "前序遍历 - 递归:" << endl; 
	preorder(L); // 前序遍历 - 递归
	cout << endl << endl;
	cout << "中序遍历 - 递归:" << endl; 
	inorder(L); // 中序遍历 - 递归 
	cout << endl << endl;
	cout << "后序遍历 - 递归:" << endl; 
	postorder(L); // 后序遍历 - 递归
	cout << endl << endl;
	cout << "中序遍历:" << endl; 
	inorder3(L);
	
	L = (TBNode *)calloc(1, sizeof(TBNode));
	creat0(L); // 生成树
	creat3(L); // 后序化
	cout << "前序遍历 - 递归:" << endl; 
	preorder(L); // 前序遍历 - 递归
	cout << endl << endl;
	cout << "中序遍历 - 递归:" << endl; 
	inorder(L); // 中序遍历 - 递归 
	cout << endl << endl;
	cout << "后序遍历 - 递归:" << endl; 
	postorder(L); // 后序遍历 - 递归
	cout << endl << endl; 
	cout << "后序遍历:" << endl; 
	postorder3(L);

} 

void creat0(TBLink &L) // 生成 普通树结点 
{
	int t,length = rand()%num;  
	cout << "随机生成 " << length << "个元素" << endl;
	if(length > 0)
	{
		L = (TBNode *)calloc(1, sizeof(TBNode));
		L->data = rand()%max;
		
		t = 0;
		creatTree(L->lchild, t, (length-1)/2);
		t = 0;
		creatTree(L->rchild, t, length-1-(length-1)/2);
		
		cout << "创建成功!" << endl << endl;
	}
	else
	{
		L = NULL;
		cout << "树为空!" << endl << endl; 
	}
}

void creatTree(TBLink &L, int &n, int length)
{
	if(n < length) 
	{
		TBLink p;
		p = (TBNode *)calloc(1, sizeof(TBNode));
		p->data = rand()%max;
		L = p;
		n++;
		creatTree(L->lchild, n, length);
		creatTree(L->rchild, n, length);
	}
}

void creat1(TBLink &L) // 前序线索化 
{
	cout << "尝试前序线索化..." << endl ;
	if(L != NULL)
	{
		TBLink pre = NULL;
		precreat(L, pre);
		pre->rchild = NULL;
		
		pre->rtag = 1;
		cout << "成功!"  << endl << endl;
	}
	else
		cout << "树为空!" << endl << endl; 
}

void precreat(TBLink &L, TBLink &pre) // 跟 creat1() 前序线索化
{
	if(L != NULL)
	{
		if(L->lchild == NULL)
		{
			L->lchild = pre;
			L->ltag = 1;
		}
		if(pre != NULL && pre->rchild == NULL)
		{
			pre->rchild = L;
			pre->rtag = 1;
		}
		pre = L;
		if(L->ltag == 0)
			precreat(L->lchild, pre);
		if(L->rtag == 0)
			precreat(L->rchild, pre);
	}
}

void preorder(TBLink L) // 前序遍历递归
{
	if(L != NULL)
	{
		cout << L->data << " ";
		if(L->ltag == 0)
			preorder(L->lchild);
		if(L->rtag == 0 )
			preorder(L->rchild);
	}
}

void preorder3(TBLink L)
{
	if(L != NULL)
	{
		TBLink p;
		p = L;
		while(p != NULL)
		{
			while(p->ltag == 0)
			{
				cout << p->data << " ";
				p = p->lchild;
			}
			cout << p->data << " ";
			p = p->rchild; 
		}
	}
}

void creat2(TBLink &L) // 中序线索化 
{
	cout << "尝试中序线索化..." << endl ;
	if(L != NULL)
	{
		TBLink pre = NULL;
		increat(L, pre);
		pre->rchild = NULL;
		
		pre->rtag = 1;
		cout << "成功!"  << endl << endl;
	}
	else
		cout << "树为空!" << endl << endl; 
}

void increat(TBLink &L, TBLink &pre)
{
	if(L != NULL)
	{
		increat(L->lchild, pre); // 左子树 线索化 
		if(L->lchild == NULL) // 前驱线索 
		{
			L->lchild = pre;
			L->ltag = 1;
		}
		if(pre != NULL && pre->rchild == NULL) // 后继线索 
		{
			pre->rchild = L;
			pre->rtag = 1;
		}
		
		pre = L; 
		increat(L->rchild, pre); // 右子树 线索化 
	}
}

void inorder(TBLink L) // 中序遍历递归 
{
	if(L != NULL)
	{
		if(L->ltag==0)
			inorder(L->lchild);
		cout << L->data << " " ;
		if(L->rtag==0)
			inorder(L->rchild);
	}
}

TBLink first(TBLink L) 
{
	while(L->ltag == 0)
		L = L->lchild;
	return L;
}

TBLink next(TBLink L)
{
	if(L->rtag == 1) // 后继 
		return L->rchild;
	else
		return first(L->rchild); // 右子树的 左下角 
}

void inorder3(TBLink L) // 中序遍历  
{
	TBLink p;
	for(p = first(L); p != NULL; p = next(p)) 
		cout << p->data << " " ;
	cout << endl << endl;
}

void creat3(TBLink &L) // 后序化
{
	cout << "尝试后序线索化..." << endl ;
	if(L != NULL)
	{
		TBLink pre = NULL;
		postcreat(L, pre); //最后一个结点是根结点,前驱后继均为 0! 
		if(L->rchild == NULL) 
		{
			L->rtag = 1;
		}
		cout << "成功!"  << endl << endl;
	}
	else
		cout << "树为空!" << endl << endl; 
}

void postcreat(TBLink &L, TBLink &pre)
{
	if(L != NULL)
	{
		postcreat(L->lchild,pre);
		postcreat(L->rchild,pre);
		if(L->lchild == NULL) // 前驱 
		{
			L->lchild = pre;
			L->ltag = 1; 
		}
		if(pre != NULL && pre->rchild == NULL) 
		{
			pre->rchild = L;
			pre->rtag = 1;
		}
		pre = L;
	}
}

void postorder(TBLink L)
{
	if(L != NULL)
	{
		if(L->ltag == 0) 
			postorder(L->lchild);
		if(L->rtag == 0)
			postorder(L->rchild);
		cout << L->data << " ";
	}
}

void postorder3(TBLink L)
{
	if(L != NULL )
	{
		cout << "待续..." << endl << endl; 	
	}
} 

2 运行结果

2.1 前序线索二叉树

2.2 中序线索二叉树

2.3 后序线索二叉树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值