【【异世界历险之数据结构世界(二叉树)】】

前言

介绍

二叉树的三种遍历:

  1. 前序遍历 Preorder Traversal
    访问顺序: 根节点 → 左子树 → 右子树
    ✅ 根在最前
  2. 中序遍历 Inorder Traversal
    访问顺序: 左子树 → 根节点 → 右子树
    ✅ 根在中间
  3. 后序遍历 Postorder Traversal
    访问顺序: 左子树 → 右子树 → 根节点
    ✅ 根在最后

假设二叉树结构如下:

复制代码
    A
   / \
  B   C
 / \   \
D   E   F

🌼 前序遍历(Preorder)

顺序:A B D E C F

🌸 中序遍历(Inorder)

顺序:D B E A C F

🌷 后序遍历(Postorder)

顺序:D E B F C A

实现

前提

c 复制代码
typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

构建树

c 复制代码
BTNode* BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	
	newnode->val = x;
	newnode->left = NULL;
	newnode->right = NULL;
	return newnode;

}

BTNode* CreateTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);

	node1->left = node2;
	node1->right = node3;
	node2->left = node4;
	node2->right = node5;
	node3->left = node6;
	node3->right = node7;

	return node1;

}
解析:

✅ BuyNode 函数解析:

作用:创建一个新的二叉树节点,值为 x。
✅ CreateTree 函数解析:

作用:构建一棵固定结构的完全二叉树,节点值为 1~7。

构建逻辑如下:

复制代码
    1
   / \
  2   3
 / \  / \
4  5 6  7

最终返回根节点 node1,可用于后续遍历或操作。

一、前序遍历

c 复制代码
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%d ", root->val);
	PreOrder(root->left);
	PreOrder(root->right);
}
解析:

前序遍历顺序: 根节点 → 左子树→ 右子树
PreOrder(root) 展开步骤(根 → 左 → 右)如下:

第一次调用:PreOrder(1)

打印:1

调用左子树:PreOrder(2)

第二次调用:PreOrder(2)

打印:2

调用左子树:PreOrder(4)

第三次调用:PreOrder(4)

打印:4

调用左子树:PreOrder(NULL) → 打印:NULL

调用右子树:PreOrder(NULL) → 打印:NULL

(回到上一层)

回到:PreOrder(2),接着调用右子树:PreOrder(5)

第四次调用:PreOrder(5)

打印:5

左:PreOrder(NULL) → 打印:NULL

右:PreOrder(NULL) → 打印:NULL

(回到上一层)

回到:PreOrder(1),接着调用右子树:PreOrder(3)

第五次调用:PreOrder(3)

打印:3

调用左子树:PreOrder(6)

第六次调用:PreOrder(6)

打印:6

左:PreOrder(NULL) → 打印:NULL

右:PreOrder(NULL) → 打印:NULL

回到:PreOrder(3),接着调用右子树:PreOrder(7)

第七次调用:PreOrder(7)

打印:7

左:PreOrder(NULL) → 打印:NULL

右:PreOrder(NULL) → 打印:NULL

二、中序遍历

c 复制代码
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%d ", root->val);
	InOrder(root->right);
}
解析:

中序遍历顺序:

左子树 → 根节点 → 右子树

三、后序遍历

c 复制代码
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->val);

}
解析:

后序遍历顺序:

左子树 → 右子树 → 根节点

三次遍历结果展示(前,中,后)


四、节点个数

c 复制代码
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left)
		                    + TreeSize(root->right) 
		                    + 1;
}

解析:

➤ TreeSize(1)

= TreeSize(2) + TreeSize(3) + 1

➤ TreeSize(2)

= TreeSize(4) + TreeSize(5) + 1

TreeSize(4) → 左空 + 右空 + 1 = 0 + 0 + 1 = 1

TreeSize(5) → 左空 + 右空 + 1 = 0 + 0 + 1 = 1

→ 所以 TreeSize(2) = 1 + 1 + 1 = 3

➤ TreeSize(3)

= TreeSize(6) + TreeSize(7) + 1

TreeSize(6) → 左空 + 右空 + 1 = 0 + 0 + 1 = 1

TreeSize(7) → 左空 + 右空 + 1 = 0 + 0 + 1 = 1

→ 所以 TreeSize(3) = 1 + 1 + 1 = 3

🔚 回到 TreeSize(1)

= 左(3) + 右(3) + 1 = 7

五、树的高度

c 复制代码
int TreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return (leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1);
}
解析:

TreeHeight(1)

= max(TreeHeight(2), TreeHeight(3)) + 1
TreeHeight(2)

= max(TreeHeight(4), TreeHeight(5)) + 1

→ TreeHeight(4) = 1(左右都是 NULL)

→ TreeHeight(5) = 1

→ TreeHeight(2) = max(1, 1) + 1 = 2
TreeHeight(3)

= max(TreeHeight(6), TreeHeight(7)) + 1

→ TreeHeight(6) = 1

→ TreeHeight(7) = 1

→ TreeHeight(3) = max(1, 1) + 1 = 2
最终:
TreeHeight(1) = max(2, 2) + 1 = 3

六、树的第k层节点数

c 复制代码
int TreeLevel(BTNode* root,int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	int leftLevel = TreeLevel(root->left, k - 1);
	int rightLevel = TreeLevel(root->right, k - 1);

	return leftLevel + rightLevel;
}
解析:以k=3为例子

TreeLevel(1, 3)

= TreeLevel(2, 2) + TreeLevel(3, 2)

TreeLevel(2, 2)

= TreeLevel(4,1) + TreeLevel(5,1)

→ 都是第 3 层节点,返回 1 + 1 = 2

TreeLevel(3, 2)

= TreeLevel(6,1) + TreeLevel(7,1)

→ 返回 1 + 1 = 2
最终:
TreeLevel(1,3) = 2 + 2 = 4

七、查找值为x的节点地址

c 复制代码
BTNode* TreeFind(BTNode* root,BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	BTNode* left = TreeFind(root->left, x);
	if (left)
		return left;
	BTNode* right = TreeFind(root->right, x);
	if (right)
		return right;

	return NULL;
}
解析:

TreeFind(1, 6)

→ root->val != 6,查左子树

TreeFind(2, 6)

→ root->val != 6,查左子树

TreeFind(4, 6)

→ 不等,左右 NULL,返回 NULL

回到 TreeFind(2),查右子树

TreeFind(5, 6)

→ 不等,左右 NULL,返回 NULL

回到 TreeFind(1),查右子树

TreeFind(3, 6)

→ root->val != 6,查左子树

TreeFind(6, 6)

匹配成功!返回该节点指针
最终一路上传返回到 TreeFind(1)

结果展示·:

总结

断更许久,抱歉各位。
堆与二叉树(复习)

相关推荐
祖力5519 小时前
数据结构的基本概念与单向链表(链表数据类型构造、创建、头插、尾插、头删、尾删)
数据结构·链表
大明者省21 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7981 天前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2581 天前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记1 天前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI1 天前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型1 天前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光1 天前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院1 天前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡1 天前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构