线索二叉树的创建 c语言 数据结构 简单易懂 超详细~~

#include<stdio.h>
#include<stdlib.h>
//创建枚举类型
typedef enum{link,thread} PointNag;//link(0)表示是指向的是左右孩子
//thread(1)表示的是前驱结点和后继节点
typedef char Elemtype;
//创建二叉节点
typedef struct BiThrnode
{
Elemtype data;
struct BiThrnode* lchild, * rchild;
PointNag ltag;
PointNag rtag;//枚举类型,表示0和1

}BiThrnode,BiThrTree;
//创建树(通过前序遍历的方式)
void createBiThrnode(BiThrTree
T)
{
char c;
scanf_s("%c", &c);
if (c == ’ ')
{
*T = NULL;
}
else
{
T = (BiThrnode)malloc(sizeof(BiThrnode));
(*T)->data = c;
(*T)->ltag = link;
(*T)->rtag = link;//在创建的时候默认为左孩子和有孩子
//在中序遍历的时候如果没有左右孩子,在修改该节点的指针
//如果该节点有左右孩子,就可以不管他

	//创建左子树
	createBiThrnode(&(*T)->lchild);
	//创建右子树
	createBiThrnode(&(*T)->rchild);
}

}
BiThrTree pre;//头指针
//中序遍历树 递归线索化
void inThreading(BiThrTree* T)
{
if (!T)//该树不是一个空树
{
inThreading(&(*T)->lchild);//一直走到最左边的节点
//节点处理
if (!(*T)->lchild)//如果T的左子树为空,那么就需要将
//该左子树的左孩子指向该节点的前驱结点
//由于已经遍历完前驱结点,那么就找不到这个前驱结点
//所以我们需要用一个全局变量来保存它
//当过了这个节点之后,全局变量的这个前驱结点就是这个刚刚经过的结点

	{
		(*T)->ltag = thread;//将该结点首先置为线索化的结点
		(*T)->lchild = pre;
	}
	if (!pre->rchild)//不能用T来遍历它的右节点,因为T的上一层的右节点还没有遍历完成
	{//如果右节点为空,那么需要将pre的右节点指向为pre的后继节点,
		//而pre的后继结点就为T(从上到下开始想)
		pre->rtag = thread;
		pre->rchild = *T;
	}
	//这一小子树遍历完成之后又到该子树的上一级
	pre = *T;
	inThreading(&(*T)->rchild);
}

}
void inorderThreading(BiThrTree *p,BiThrTree T)//第一个参数为头指针
{//T为一棵树
p = (BiThrnode)malloc(sizeof(BiThrnode));
(*p)->ltag = link;//头指针的左孩子指向一个结点
(*p)->rtag = thread;//头指针的右孩子指向一个线索
//为什么要将头指针的右孩子指向为一个线索呢?因为方便首位相连接
//最后一个结点指向头指针,头指针指向最后一个结点 (首尾相接,有点像双向链表)
(*p)->rchild = *p;
if (!T)//该树为一颗空树
{
(*p)->lchild = *p;
}
else
{
(*p)->lchild = T;
pre = *p;//将刚刚创建的头指针的地址赋给全局变量pre
inThreading(&T);
//首尾连接
//pre在递归完成之后已经变成了右边最后一个结点了
pre->rchild = *p;
(p)->rchild = pre;
pre->rtag = thread;
}
}
int main(void)
{
BiThrTree T;
BiThrTree
p=NULL;
createBiThrnode(&T);
inorderThreading(p, T);//注意第一个参数传递的是那个全局变量pre哦
system(“pause”);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言实现先序线索二叉树的代码: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树结点结构 typedef struct TreeNode { char data; struct TreeNode* left; struct TreeNode* right; int leftTag; // 左线索标志,0表示指向左子,1表示指向前驱结点 int rightTag; // 右线索标志,0表示指向右子,1表示指向后继结点 } TreeNode; // 创建一个新结点 TreeNode* createNode(char data) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->data = data; newNode->left = NULL; newNode->right = NULL; newNode->leftTag = 0; newNode->rightTag = 0; return newNode; } // 构建先序线索二叉树 void createPreThread(TreeNode* root, TreeNode** pre) { if (root == NULL) { return; } if (root->left == NULL) { root->left = *pre; root->leftTag = 1; } if (*pre != NULL && (*pre)->right == NULL) { (*pre)->right = root; (*pre)->rightTag = 1; } *pre = root; if (root->leftTag == 0) { createPreThread(root->left, pre); } if (root->rightTag == 0) { createPreThread(root->right, pre); } } // 先序遍历先序线索二叉树 void preOrderTraversal(TreeNode* root) { TreeNode* current = root; while (current != NULL) { printf("%c ", current->data); if (current->leftTag == 0) { current = current->left; } else { current = current->right; } } } int main() { // 创建二叉树结点 TreeNode* root = createNode('A'); TreeNode* nodeB = createNode('B'); TreeNode* nodeC = createNode('C'); TreeNode* nodeD = createNode('D'); TreeNode* nodeE = createNode('E'); TreeNode* nodeF = createNode('F'); // 构建二叉树 root->left = nodeB; root->right = nodeC; nodeB->left = nodeD; nodeB->right = nodeE; nodeC->right = nodeF; // 创建先序线索二叉树 TreeNode* pre = NULL; createPreThread(root, &pre); // 先序遍历先序线索二叉树 printf("先序遍历先序线索二叉树:"); preOrderTraversal(root); return 0; } ``` 这段代码使用先序遍历的方式构建了一个先序线索二叉树,并实现了对先序线索二叉树进行先序遍历输出。你可以根据需要修改数据类型或结点的值来适应不同的场景。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值