线索二叉树的C语言实现

先序的倒序输出和后序的正序输出懒得写了

#include<stdio.h>
#include<stdlib.h>

typedef struct P {
	int data;
	struct P* l,* r;
	int lt, rt;
}P, *p;

void Init(p* T, int e) {
	p t = *T;
	t = (p)malloc(sizeof(P));
	t->data = e;
	t->l = t->r = NULL;
	t->lt = t->rt = 0;
	(*T) = t;
}

void setTree(p* T, int e) {
	p t = *T; int a, b, n, m;
	if (t == NULL)Init(&t, e);
	else t->data = e;
	scanf_s("%d %d %d %d", &a, &b, &n, &m);//a、n为0则不建分支,b、m为值,若无则为0
	if (a)setTree(&t->l, b);
	if (n)setTree(&t->r, m);
	(*T) = t;
}

void setTopInTread(p t, p* pre) {
	p pr = *pre;//t为当前节点,pr为当前头节点
	if (t) {
		//setInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
		if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
		if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
		pr = t;//更新头结点为当前节点
		if (!t->lt)//左孩子可能会指向前趋,
			setTopInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
		if (!t->rt)//右孩子可能已经指向后继
			setTopInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
	}
	(*pre) = pr;
}

void setLastInTread(p t, p* pre) {//建立线索二叉树
	p pr = *pre;//t为当前节点,pr为当前头节点
	if (t) {//中序遍历时左右孩子不可能先指向前趋或后继
		if (!t->lt&& t->l)//防止pr变为NULL
			setLastInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
		if (!t->rt && t->r)
			setLastInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
		if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
		if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
		pr = t;//更新头结点为当前节点
	}
	(*pre) = pr;
}

void setMidInTread(p t, p* pre) {//建立线索二叉树
	p pr = *pre;//t为当前节点,pr为当前头节点
	if (t) {//中序遍历时左右孩子不可能先指向前趋或后继
		setMidInTread(t->l, &pr);//遍历左子树,此时头结点更新为左子树的最右节点
		if (!t->l) t->l = pr, t->lt = 1;//左子树为空,链接前驱
		if (pr && !pr->r)pr->r = t, pr->rt = 1;//头结点无右子树,更新头结点后继为当前节点
		pr = t;//更新头结点为当前节点
		setMidInTread(t->r, &pr);//遍历右子树,此时头结点更新为右子树的最右节点
	}
	(*pre) = pr;
}

void createLastInTread(p t) {//开始建立线索二叉树
	p pr = NULL;
	if (t) {
		setLastInTread(t, &pr);
		//pr->r = NULL;//中序遍历末尾节点指向空
		//pr->rt = 1;
	}
}

void createMidInTread(p t) {//开始建立线索二叉树
	p pr = NULL;
	if (t) {
		setMidInTread(t, &pr);
		pr->r = NULL;//中序遍历末尾节点指向空
		pr->rt = 1;
	}
}

void createTopInTread(p t) {//开始建立线索二叉树
	p pr = NULL;
	if (t) {
		setTopInTread(t, &pr);
		pr->r = NULL;//中序遍历末尾节点指向空
		pr->rt = 1;
	}
}

p getMostLeft(p T) {//找到最左
	while (T->lt == 0 && T->l)T = T->l;
	return T;
}

p getMostRight(p T) {
	while (!T->rt)T = T->r;
	return T;
}

p getTopLast(p T) {
	while (!T->lt || !T->rt)
		if (!T->rt)T = T->r;
		else if (!T->lt) T = T->l;
	return T;
}

p getLastTop(p T) {
	while (!T->lt || !T->rt)
		if (!T->lt)T = T->l;
		else if (!T->rt)T = T->r;
	return T;
}

void print_last_Tree(p T) {
	printf("后序线索二叉树不可直接找到后继");
}

void Lastprint_last_Tree(p T) {//线索后序倒叙遍历
	for (p t = T; t; t = ((!t->lt||!t->rt)? (!t->rt?t->r: t->l) : t->l))
		printf("%d ", t->data);
}

void print_top_Tree(p T) {//线索先序遍历
	for (p t = T; t; t = (t->rt ? t->r : (t->lt ? t->r : t->l)))
		printf("%d ", t->data);
}

void Lastprint_top_Tree(p T) {//线索先序倒叙遍历
	printf("先序线索二叉树不可直接找到前驱");
}

void print_mid_Tree(p T) {//线索中序遍历
	for (p t = getMostLeft(T); t; t = (!t->rt ? getMostLeft(t->r) : t->r))
		printf("%d ", t->data);
}

void Lastprint_mid_Tree(p T) {//线索中序倒叙遍历
	for (p t = getMostRight(T); t; t = (!t->lt ? getMostRight(t->l) : t->l))
		printf("%d ", t->data);
}

void point_top(p T) {//正常遍历
	printf("%d ", T->data);
	if (T->l)point_top(T->l);
	if (T->r)point_top(T->r);
}

void point_last(p T) {//正常遍历
	if (T->l)point_last(T->l);
	if (T->r)point_last(T->r);
	printf("%d ", T->data);
}

void point_mid(p T) {//正常遍历
	if (T->l)point_mid(T->l);
	printf("%d ", T->data);
	if (T->r)point_mid(T->r);
}

int main() {
	p T = NULL, T1 = NULL, T2 = NULL;
	int n;
	scanf_s("%d", &n);
	setTree(&T, n); setTree(&T1, n); setTree(&T2, n);
	/*中序遍历*/
	printf("中序遍历的正常、线索、倒叙线索:\n");
	point_mid(T); printf("\n");
	createMidInTread(T);
	print_mid_Tree(T); printf("\n");
	Lastprint_mid_Tree(T); printf("\n");
	printf("*****************************\n");
	/*先序遍历*/
	printf("先序遍历的正常、线索、倒叙线索:\n");
	point_top(T1); printf("\n");
	createTopInTread(T1);
	print_top_Tree(T1); printf("\n");
	Lastprint_top_Tree(T1); printf("\n");
	printf("*****************************\n");
	/*后序遍历*/
	printf("后序遍历的正常、线索、倒叙线索:\n");
	point_last(T2), printf("\n");
	createLastInTread(T2);
	print_last_Tree(T2); printf("\n");
	Lastprint_last_Tree(T2), printf("\n");
	printf("*****************************\n");
	return 0;
}
/*分别各建了一次树,懒得改了
1
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
1 2 1 3
1 4 1 5
0 0 1 6
0 0 0 0
0 0 0 0
1 7 0 0
0 0 1 8
0 0 0 0
*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是线索二叉树C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义线索二叉树结构体 typedef struct ThreadedBinaryTreeNode { int data; struct ThreadedBinaryTreeNode *left, *right; int ltag, rtag; // 0表示指向左右子树,1表示指向前驱或后继 } ThreadedBinaryTreeNode, *ThreadedBinaryTree; // 中序遍历线索化 void InThread(ThreadedBinaryTree p, ThreadedBinaryTree *pre) { if (p != NULL) { InThread(p->left, pre); if (p->left == NULL) { p->left = *pre; p->ltag = 1; } if (*pre != NULL && (*pre)->right == NULL) { (*pre)->right = p; (*pre)->rtag = 1; } *pre = p; InThread(p->right, pre); } } // 创建线索二叉树 void CreateInThread(ThreadedBinaryTree *root) { ThreadedBinaryTree pre = NULL; if (*root != NULL) { InThread(*root, &pre); pre->right = NULL; pre->rtag = 1; } } // 中序遍历线索二叉树 void InOrderTraverse(ThreadedBinaryTree root) { ThreadedBinaryTree p = root; while (p != NULL) { while (p->ltag == 0) { p = p->left; } printf("%d ", p->data); while (p->rtag == 1 && p->right != NULL) { p = p->right; printf("%d ", p->data); } p = p->right; } } // 测试 int main() { // 创建线索二叉树 ThreadedBinaryTree root = (ThreadedBinaryTree)malloc(sizeof(ThreadedBinaryTreeNode)); root->data = 1; root->ltag = root->rtag = 0; root->left = (ThreadedBinaryTree)malloc(sizeof(ThreadedBinaryTreeNode)); root->left->data = 2; root->left->ltag = root->left->rtag = 0; root->left->left = root->left->right = NULL; root->right = (ThreadedBinaryTree)malloc(sizeof(ThreadedBinaryTreeNode)); root->right->data = 3; root->right->ltag = root->right->rtag = 0; root->right->left = (ThreadedBinaryTree)malloc(sizeof(ThreadedBinaryTreeNode)); root->right->left->data = 4; root->right->left->ltag = root->right->left->rtag = 0; root->right->left->left = root->right->left->right = NULL; root->right->right = (ThreadedBinaryTree)malloc(sizeof(ThreadedBinaryTreeNode)); root->right->right->data = 5; root->right->right->ltag = root->right->right->rtag = 0; root->right->right->left = root->right->right->right = NULL; CreateInThread(&root); // 中序遍历线索二叉树 InOrderTraverse(root); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值