二叉树的基本数据结构类型(c语言)

二叉树基本数据结构与实现总结


数据结构设计

一、树节点结构

c 复制代码
typedef struct TreeNode {
	eleType val;
	struct TreeNode* left;
	struct TreeNode* right;
} TreeNode;


说明:

  1. 成员变量 :
    • val: 节点的值(类型为 eleType,此处定义为 char)。
    • leftright: 指向左右子节点的指针,分别表示节点的左子树和右子树。
  2. 用途 :
    • 表示树的基本组成单元,每个节点存储数据并连接到其左右子节点。

二、树的整体结构

c 复制代码
typedef struct Tree {
	TreeNode* nodes;  // 存储所有节点的数组
	TreeNode* root;   // 指向树的根节点
	size_t nodeSize;  // 树的节点总数
} Tree;

说明:

  1. 成员变量 :
    • nodes: 动态分配的 TreeNode 数组,用于存储树的所有节点。
    • root: 指向根节点,表示二叉树的入口。
    • nodeSize: 记录树中节点的总数量。
  2. 用途 :
    • 包装整个二叉树的结构,提供统一管理节点及树的接口。

三、树的基本操作

3.1. 初始化树

c 复制代码
void Init_Tree(Tree* T, int size)
{
	T->nodeSize = size;
	T->nodes = (TreeNode*)malloc(sizeof(TreeNode) * size);
	T->root = NULL;
}

功能:

  • 动态分配内存以存储 size 个节点。
  • 初始化树的节点数组、根节点指针以及节点数量。

关键点:

  • 动态分配内存时,需保证后续释放操作。
  • root 设置为 NULL 表示树为空。

3.2. 销毁树

c 复制代码
void Destory_Tree(Tree* T)
{
	free(T->nodes);
	T->nodes = NULL;
	T->nodeSize = 0;
	T->root = NULL;
}

功能:

  • 释放动态分配的内存,清空树的所有数据。

关键点:

  • 指针置为 NULL,避免悬空指针问题。

3.3. 获取节点

c 复制代码
TreeNode* GetNode_Tree(Tree* T, int id)
{
	return &T->nodes[id];
}

功能:

  • 根据节点的下标直接访问节点数组中的节点。

关键点:

  • 数组下标需在合法范围内,否则可能访问无效内存。

3.4. 创建二叉树

递归创建函数
c 复制代码
//a-->元素数组,nodeId-->根节点下标, Nullnode-->空节点标识符
TreeNode* Creat_Recursively(Tree* T, eleType a[], int size, int nodeId, eleType NullNode)
{
	if (nodeId >= size || a[nodeId] == NullNode)	
	{
		return NULL;
	}
	TreeNode* nowNode = GetNode_Tree(T, nodeId);
	nowNode->val = a[nodeId];
	nowNode->left = Creat_Recursively(T, a, size, nodeId * 2, NullNode);
	nowNode->right = Creat_Recursively(T, a, size, nodeId * 2 + 1, NullNode);
	return nowNode;
}

功能:

  • 按照完全二叉树的层序布局递归创建节点。

实现逻辑:
1):递归终止条件

当节点超出数组范围,或节点值为 NullNode 时,返回空树(NULL)
2):创建当前节点 :

从节点数组中获取节点并赋值。
3):递归创建子树 :

递归调用自身,分别创建左子树(nodeId * 2)和右子树(nodeId * 2 + 1)

注意:

  • 输入数组需按照完全二叉树的顺序存储,根节点下标从 1 开始。
3.5封装创建函数
c 复制代码
void Creat_binaryTree(Tree* T, eleType a[], int size, eleType nullNode)
{
	T->root = Creat_Recursively(T, a, size, 1, nullNode);
}

功能:

  • 对递归创建函数进行封装,默认从根节点开始。

四. 遍历二叉树

4.1、前序遍历
c 复制代码
void preOrder(Tree* T, TreeNode* node)
{
	if (node)
	{
		visit(node);
		preOrder(T, node->left);
		preOrder(T, node->right);
	}
}

顺序:

  • 根 -> 左子树 -> 右子树

4.2、中序遍历
c 复制代码
void InOrder(Tree* T, TreeNode* node)
{
	if (node)
	{
		InOrder(T, node->left);
		visit(node);
		InOrder(T, node->right);
	}
}

顺序:

  • 左子树 -> 根 -> 右子树

4.3、后序遍历
c 复制代码
void PostOrder(Tree* T, TreeNode* node)
{
	if (node)
	{
		PostOrder(T, node->left);
		PostOrder(T, node->right);
		visit(node);
	} 
}

顺序:

  • 左子树 -> 右子树 -> 根

主函数

c 复制代码
int main()
{
	const char nullNode = '*';
	char a[24] = {
		nullNode,'-','+','/','a',	
		'x','e','f',nullNode,nullNode,
		'b','-',nullNode,nullNode,nullNode,
		nullNode,nullNode,nullNode,nullNode,nullNode,
		nullNode,nullNode,'c','d'
	};

	Tree T;
	Init_Tree(&T, 24);
	Creat_binaryTree(&T, a, 24, nullNode);

	printf("前序遍历:");
	preOrder(&T, T.root);
	printf("\n");

	printf("中序遍历:");
	InOrder(&T, T.root);
	printf("\n");

	printf("后序遍历:");
	PostOrder(&T, T.root);
	printf("\n");

	Destory_Tree(&T);
	system("pause");
	return 0;
}

功能:

  1. 创建并初始化一个二叉树。
  2. 使用不同遍历方式输出节点值。

五、结果演示:

六、总结

  1. 基本数据结构:

    • 树节点由 TreeNode 结构体表示,包含数据与左右子节点指针。
    • 树由 Tree 结构体管理,提供统一的入口和操作方法。
  2. 树的操作:

    • 包含初始化、销毁、节点访问、递归创建与遍历操作,覆盖了二叉树的主要功能。
  3. 实现技巧:

    • 使用数组模拟完全二叉树,方便递归创建。
    • 遍历函数通过递归实现,逻辑清晰简洁。
相关推荐
ᐇ9593 小时前
Java集合框架深度实战:构建智能教育管理与娱乐系统
java·开发语言·娱乐
梁正雄4 小时前
1、python基础语法
开发语言·python
.YM.Z4 小时前
【数据结构】:排序(一)
数据结构·算法·排序算法
强化学习与机器人控制仿真4 小时前
RSL-RL:开源人形机器人强化学习控制研究库
开发语言·人工智能·stm32·神经网络·机器人·强化学习·模仿学习
百***48074 小时前
【Golang】slice切片
开发语言·算法·golang
q***92514 小时前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
仟濹4 小时前
【Java 基础】面向对象 - 继承
java·开发语言
郝学胜-神的一滴5 小时前
Linux命名管道:创建与原理详解
linux·运维·服务器·开发语言·c++·程序人生·个人开发
智者知已应修善业5 小时前
【51单片机普通延时奇偶灯切换】2023-4-4
c语言·经验分享·笔记·嵌入式硬件·51单片机
2501_941623325 小时前
C++高性能网络服务器与epoll实战分享:大规模并发连接处理与事件驱动优化经验
开发语言·php