线索二叉树—C语言实现

线索二叉树的定义如下:
https://www.jianshu.com/p/3965a6e424f5
程序实现:

//线索二叉树
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>

typedef char ElemType;
typedef struct BITNODE //二叉树的结点
{
	ElemType Data;
	struct BITNODE *leftchild; //指向左孩子地址的指针
	struct BITNODE *rightchild; //指向右孩子地址的指针
	int ltag; //ltag为0时leftchild指向该结点的左孩子,为1时指向该结点的前驱
	int rtag; //rtag为0时rightchild指向该结点的右孩子,为1时指向该结点的后继
}BiTNode, *BiTree;

BiTree pre; //表示刚刚遍历过的前一个结点
int sum; //记录叶结点数

//创建二叉树—前序创建,约定用户遵照前序遍历的方式输入数据
void CreatBinaryTree_first(BiTree *T)
{
	ElemType c;
	scanf("%c", &c);

	if (c == ' ')
	{
		*T = NULL;
	}
	else
	{
		*T = (BiTNode*)malloc(sizeof(BiTNode));
		(*T)->Data = c;
		(*T)->ltag = 0;
		(*T)->rtag = 0; //先初始化leftchild和rightchild指向结点的左孩子和右孩子,在遍历线索化过程中更改
		CreatBinaryTree_first(&(*T)->leftchild);
		CreatBinaryTree_first(&(*T)->rightchild);
	}
}
//遍历二叉树过程要进行的操作
void visit(ElemType c)
{
	//显示各结点
	printf("%c", c);
}
//叶子结点总数
void leafnodenum(BiTree T)
{
	if (T->ltag == 1 && T->rtag ==1)
	{
		sum += 1;
	}
}
//中序遍历线索化—遍历线索二叉树要采用中序遍历
void inorder(BiTree T)
{
	if (T)
	{
		inorder(T->leftchild);
		//visit(T->Data);
		//leafnodenum(T);
		if (!T->leftchild)
		{
			T->ltag = 1;
			T->leftchild = pre;
		}
		if (!pre->rightchild) //不能是T->rightchild,因为还没走过后继结点,不知道后继结点是哪个
		{
			pre->rtag = 1;
			pre->rightchild = T;
		}
		pre = T;
		inorder(T->rightchild);
	}
}
//初始化一个头指针-pre,指向树的根节点
void InOrderThreading(BiTree *p, BiTree T)
{
	*p = (BiTNode *)malloc(sizeof(BiTNode));
	(*p)->ltag = 0;
	(*p)->rtag = 1;
	(*p)->rightchild = *p;
	if (!T) //如果二叉树不存在
	{
		(*p)->leftchild = *p;
	}
	else
	{
		(*p)->leftchild = T;
		pre = *p;
		inorder(T);
		//令头指针和树的最后结点连接起来
		pre->rightchild = *p;
		pre->rtag = 1;
		(*p)->rightchild = pre;
	}
}

//中序遍历—执行需要的操作
void inordertree(BiTree P)
{
	BiTree T;
	T = P->leftchild;
	while (T != P)
	{
		while (T->ltag == 0)
		{
			T = T->leftchild;
		}
		visit(T->Data);//输出结点
		leafnodenum(T);//计算叶结点总数
		while (T->rtag == 1 && T->rightchild != P)
		{
			T = T->rightchild;
			visit(T->Data);
			leafnodenum(T);
		}
		T = T->rightchild;
	}

}
int main()
{
	BiTree T = NULL;
	BiTree P = NULL;

	CreatBinaryTree_first(&T);
	InOrderThreading(&P, T); //总的初始化结束

	printf("中序遍历的顺序为:\n");
	inordertree(P); //执行操作
	printf("\n叶结点数为:%d \n", sum);

	system("pause");
	return 0;
}

注意:在创建二叉树时要使用二级指针作为参数传入。 因为如果希望在一个函数的参数中改变一个指针的值,只能传这个指针的指针给这个函数。我理解的意思就是,如果我们调用函数时传入一个指针参数,我们在这个函数中不能修改这个指针的值,只能修改这个指针指向的内容,如果想要修改它的值,就必须把这个指针的指针作为参数传进去。

运行结果:
在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是线索二叉树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; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值