数据结构(二叉树)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

二叉树是计算机科学中最基础且重要的数据结构之一,广泛应用于算法设计、数据存储和系统优化等领域。


一、二叉树是什么?

二叉树(Binary Tree)是计算机科学中最基础且重要的非线性数据结构之一。它是由结点(Node)组成的层次结构,每个结点最多有两个子结点,分别称为 左子结点(Left Child)右子结点(Right Child)

二叉树的基本概念

  1. 根结点(Root):位于树顶端的结点,没有父结点,是整个二叉树的起点。
  2. 子结点(Child):一个结点的直接后继结点称为子结点。
  3. 父结点(Parent):一个结点的直接前驱结点称为父结点。
  4. 叶结点(Leaf):没有子结点的结点,也称为终端结点。
  5. 度(Degree):一个结点拥有的子结点数目称为度(二叉树的度最大为2)。
  6. 深度(Depth):从根结点到该结点的最长路径上的边数。
  7. 高度(Height):从该结点到最深叶结点的最长路径上的边数。

二叉树的常见类型

  1. 满二叉树(Full Binary Tree):每个结点要么是叶结点,要么恰好有两个子结点。
  2. 完全二叉树(Complete Binary Tree):除了最后一层外,其他各层的结点数都达到最大;最后一层的结点都连续集中在最左边。
  3. 平衡二叉树(Balanced Binary Tree):任意结点的左右子树的高度差不超过1(如AVL树)。
  4. 二叉搜索树(Binary Search Tree, BST):对于树中的每个结点,其左子树所有结点的值都小于该结点的值,右子树所有结点的值都大于该结点的值。
  5. 线索二叉树(Threaded Binary Tree):利用空指针存储前驱或后继结点信息,以提高遍历效率。

二叉树的基本操作

  1. 遍历(Traversal)
    • 先序遍历(Pre-order):根→左→右
    • 中序遍历(In-order):左→根→右
    • 后序遍历(Post-order):左→右→根
    • 层次遍历(Level-order):按层次从上到下,从左到右
  2. 插入(Insertion):在适当位置添加新结点
  3. 删除(Deletion):移除指定结点并保持二叉树性质
  4. 查找(Search):在树中查找特定值的结点
  5. 计算高度/深度:确定树或子树的高度/深度

二叉树的应用场景

  1. 文件系统:目录结构通常采用树形结构表示
  2. 数据库索引:B树、B+树等索引结构基于二叉树扩展
  3. 表达式求值:算术表达式可以用表达式树表示
  4. 决策树:机器学习中的决策树算法
  5. 哈夫曼编码:用于数据压缩的哈夫曼树
  6. 游戏AI:游戏中的决策树和状态空间搜索

二叉树的特点

  1. 非线性结构:相比线性结构(如数组、链表),数据关系更复杂
  2. 递归定义:每个子树本身也是一棵二叉树
  3. 高效查找:平衡二叉搜索树的查找时间复杂度为O(log n)
  4. 内存效率:相比普通树结构,二叉树每个结点最多两个指针,内存占用更少

二叉树作为基础数据结构,为理解更复杂的树结构(如红黑树、B树等)奠定了基础,在算法设计和系统实现中有着广泛的应用。

二、相关代码实现

初始化二叉树的节点

cpp 复制代码
typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;
//初始化二叉树节点

三种遍历二叉树的方式

cpp 复制代码
//二叉树前序遍历
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}
// 二叉树中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	
	PreOrder(root->left);
	printf("%d ", root->data);
	PreOrder(root->right);
}
// 二叉树后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	PreOrder(root->left);
	
	PreOrder(root->right);
	printf("%d ", root->data);
}

计算二叉树节点的个数

cpp 复制代码
//计算树的节点
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

计算树的叶子节点的个数

cpp 复制代码
//计算树的叶子节点的个数
int TreeNodeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	if (root->left==NULL&&root->right==NULL)
	{
		return 1;
	}
	
	return TreeNodeSize(root->left) + TreeNodeSize(root->right);
}
//首先叶子节点的个数=左子树叶子节点的个数+右子树叶子节点的个数
//如果左子树为空并且右子树为空则为叶子节点
//当遇到空节点直接返回0

计算树的高度

cpp 复制代码
//二叉树的高度
int TreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	int left = TreeHeight(root->left);
	int right = TreeHeight(root->right);
	return left > right ? left + 1 : right + 1;
}
//写出递推公式树的高度=max(左子树的高度,右子树的高度)+1

单值二叉树

cpp 复制代码
bool isUnivalTree(struct TreeNode* root) {
 if(root==NULL)
 {
    return true;
 }   
if(root->right)
{
    if(root->right->val!=root->val||!isUnivalTree(root->right))
    return false;
}
if(root->left)
{
    if(root->left->val!=root->val||!isUnivalTree(root->left))
    return false;
}
return true;
}
/*一棵树的所有节点都有相同的值,当且仅当对于树上的每一条边的两个端点,它们都有相同的值(这样根据传递性,所有节点都有相同的值)。

因此,我们可以对树进行一次深度优先搜索。当搜索到节点 x 时,我们检查 x 与 x 的每一个子节点之间的边是否满足要求。例如对于左子节点而言,如果其存在并且值与 x 相同,那么我们继续向下搜索该左子节点;如果值与 x 不同,那么我们直接返回 False。
*/
cs 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    // 1. 两个节点都为空:相同
    if (p == NULL && q == NULL)
        return true;
    // 2. 一个为空、一个不为空:不同
    if (p == NULL || q == NULL)
        return false;
    // 3. 节点值不同:不同
    if (p->val != q->val)
        return false;
    // 4. 递归比较左右子树(不管是否为空)
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

总结

一些相关二叉树的基本知识和一些简单的力扣题目

相关推荐
炸薯条!2 小时前
树--二叉树--堆
数据结构
z200509302 小时前
今日算法(回溯子集)
数据结构·算法·leetcode
Hesionberger2 小时前
巧用异或找出唯一数字(多解)
java·数据结构·python·算法·leetcode
变量未定义~2 小时前
阶乘的约数和、斐波那契数列、数列区间最大值(ST表)
数据结构·算法
晚风予卿云月2 小时前
二分算法练习
数据结构·c++·算法·竞赛·算法随笔
晚风予卿云月3 小时前
《二分答案》算法练习
数据结构·c++·算法·二分·竞赛·算法随笔
代码中介商4 小时前
哈希表:从O(1)查找到冲突解决全解析
数据结构·散列表
努力努力再努力wz4 小时前
【Qt入门系列】:QLabel控件详解:从文本显示到图片展示,再到内容布局与伙伴机制
android·开发语言·数据结构·数据库·c++·qt·mysql
散峰而望4 小时前
【算法练习】算法练习精选:从 Phone numbers 到 Decrease,覆盖字符串、模拟、图论思维题
数据结构·c++·算法·贪心算法·github·动态规划·图论