当前位置: 首页 > news >正文

数据结构与算法:树(Tree)精讲

“ 初音之始,响彻未来,终是末世之花 ”  ——初音未来

(ノ▽`*)ノ[换头像啦♪]=з=з=з

窝换了新主题傲 ~ 写篇博客看看效果,想要涨粉喵 =(´ω`*)=3 3 3


前言:

好的开始啦,这是一篇关于数据结构“树”的详细讲解,并辅以C++实现的博文。

文章结构清晰,从概念到实现,逐步深入,希望能帮助你更好地理解树这种重要的数据结构。


数据结构详解--树(C++实现)

(Tree) 是一种非常重要的非线性数据结构,它在现实世界和计算机科学中有着广泛的应用。

例如:文件系统、数据库索引、DOM树、组织结构图等。与线性结构(如数组、链表)不同,树能够高效地表示具有层次关系的数据~

本文将深入浅出地讲解树的核心概念、遍历方式,并使用C++实现一个基础的二叉树,及其常见操作。


一. 树的基本概念

首先,我们来了解一些关于树的核心术语:

· 节点(Node): 树的基本构成单位,包含数据项及指向其他节点的分支。

· 根节点(Root): 位于树顶端的节点,是唯--个没有父节点的节点。

· 父节点(Parent):一个节点如果有子节点,则该节点是其子节点的父节点。

· 子节点(Child):一个节点的直接后继节点。

· 兄弟节点(Sibling):具有相同父节点的节点互称为兄弟节点。

· 叶节点(Leaf):没有子节点的节点,也称为终端节点。子树(Subtree):一个节点及其所有后代节点构成的集台。

·节点的度(Degree) :一个节点拥有的子节点数。

·树的度:树中所有节点的度的最大值。

·深度(Depth):从根节点到该节点所经过的边的个数。

·高度(Height):从该节点到最远叶节点所经过的边的个数。树的高度是根节点的高度。


二、二叉树(Binary Tree)

二叉树是树结构中最常用的一种。它的特点是每个节点最多有两个子节点,通常称为左子节点(LeftChild)和右子节点(Right Child)

1.二叉树的C++节点定义

我们使用结构体来定义一个简单的二叉树节点:

#include <iostream>// 定义二叉树节点
struct TreeNode {int val;          // 节点存储的数据TreeNode* left;   // 指向左子节点的指针TreeNode* right;  // 指向右子节点的指针// 构造函数TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
2.二叉树的遍历

遍历是二叉树最基本也是最重要的操作,指的是按照某种顺序访问树中的每一个节点,且每个节点仅被访问一次。主要有四种方式:

(1)前序遍历(Preorder Traversal)

顺序:根→左子树 →右子树

应用:常用于复制整个树的结构。

void preorderTraversal(TreeNode* root) {if (root == nullptr) return; // 递归基:如果节点为空,则返回std::cout << root->val << " "; // 访问根节点preorderTraversal(root->left); // 递归遍历左子树preorderTraversal(root->right); // 递归遍历右子树
}
(2)中序遍历(Inorder Traversal)

顺序:左子树 → 根 → 右子树

应用:在二叉搜索树(BST)中,中序遍历会得到一个升序序列。

void inorderTraversal(TreeNode* root) {if (root == nullptr) return;inorderTraversal(root->left);  // 递归遍历左子树std::cout << root->val << " "; // 访问根节点inorderTraversal(root->right); // 递归遍历右子树
}
(3)后序遍历(Postorder Traversal)

顺序:左子树→右子树→根

应用:常用于释放树的内存,因为先释放子节点再释放父节点是安全的。

void postorderTraversal(TreeNode* root) {if (root == nullptr) return;postorderTraversal(root->left);  // 递归遍历左子树postorderTraversal(root->right); // 递归遍历右子树std::cout << root->val << " ";   // 访问根节点
}
(4)层序遍历(LevelOrder Traversal)

顺序:从上到下、从左到右逐层访问节点。
应用:求树的宽度、按层级处理数据。
实现:需要借助队列(Queue)这种数据结构。

#include <queue>void levelOrderTraversal(TreeNode* root) {if (root == nullptr) return;std::queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* current = q.front();q.pop();std::cout << current->val << " ";// 将当前节点的左子节点和右子节点入队if (current->left != nullptr) q.push(current->left);if (current->right != nullptr) q.push(current->right);}
}

三、完整的C++示例代码

下面是一个完整的程序,演示如何构建一个简单的二又树并进行各种遍历。

#include <iostream>
#include <queue>struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};class BinaryTree {
public:TreeNode* root;// 一个简单的创建二叉树的方法(手动构建)BinaryTree() {/* 构建如下结构的二叉树:1/ \\2   3/ \\4   5*/root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);std::cout << "二叉树创建成功!" << std::endl;}// 前序遍历void preorder(TreeNode* node) {if (node == nullptr) return;std::cout << node->val << " ";preorder(node->left);preorder(node->right);}// 中序遍历void inorder(TreeNode* node) {if (node == nullptr) return;inorder(node->left);std::cout << node->val << " ";inorder(node->right);}// 后序遍历void postorder(TreeNode* node) {if (node == nullptr) return;postorder(node->left);postorder(node->right);std::cout << node->val << " ";}// 层序遍历void levelOrder() {if (root == nullptr) return;std::queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* current = q.front();q.pop();std::cout << current->val << " ";if (current->left != nullptr) q.push(current->left);if (current->right != nullptr) q.push(current->right);}}// 释放二叉树内存(后序遍历方式)void deleteTree(TreeNode* node) {if (node == nullptr) return;deleteTree(node->left);deleteTree(node->right);std::cout << "删除节点: " << node->val << std::endl;delete node;}~BinaryTree() {std::cout << "\\n开始销毁二叉树..." << std::endl;deleteTree(root);}
};int main() {BinaryTree tree;std::cout << "前序遍历: ";tree.preorder(tree.root);std::cout << std::endl;std::cout << "中序遍历: ";tree.inorder(tree.root);std::cout << std::endl;std::cout << "后序遍历: ";tree.postorder(tree.root);std::cout << std::endl;std::cout << "层序遍历: ";tree.levelOrder();std::cout << std::endl;return 0;// tree的析构函数会自动调用,释放内存
}

输出结果:

二叉树创建成功!
前序遍历: 1 2 4 5 3
中序遍历: 4 2 5 1 3
后序遍历: 4 5 2 3 1
层序遍历: 1 2 3 4 5开始销毁二叉树...
删除节点: 4
删除节点: 5
删除节点: 2
删除节点: 3
删除节点: 1

四、树的更多类型

除了普通的二又树,还有一些非常重要且实用的变体:

1. 二叉搜索树(BST):对于任意节点,其左子树所有节点的值都小于它,右子树所有节点的值都大于它。这使得查找、插入、删除操作非常高效(平均时间复杂度O(log n))。

2. 平衡二叉搜索树(AVL树、红黑树)普通的BST在极端情况下会退化成链表。平衡树通过旋转操作自动保持树的平衡,确保操作效率稳定在O(logn)std::mapstd::set 在C++中通常用红黑树实现。

3. 堆(Heap):一种特殊的完全二叉树,常用于实现优先队列和堆排序。

4. Trie树(字典树):-专门用于处理字符串集合,常用于搜索引擎的自动补全、拼写检查等。

总结

树是一种功能强大且灵活的数据结构,它为我们处理层次化、关联性数据提供了理想的模型。理解二叉树的基本概念、遍历方式及其C++实现,是学习更复杂树结构(如BST、AVL、B树等)的坚实基础。

希望这篇博文能帮助你打开树结构的大门!在后续的学习中可以重点关注二叉搜索树和平衡二叉树,它们是面试和实际项目中应用最广泛的树结构之一。


最后,希望看到这里的Oler们,给个点赞和关注吧,我真的很想涨粉。ヽ(`⌒´メ)ノ嗷嗷嗷~~~

http://www.dtcms.com/a/606165.html

相关文章:

  • AI入门系列之GraphRAG使用指南:从环境搭建到实战应用
  • 【SolidWorks】默认模板设置
  • 基于秩极小化的压缩感知图像重建的MATLAB实现
  • 无人机图传模块技术要点与难点
  • Spring Cloud Alibaba 2025.0.0 整合 ELK 实现日志
  • AI+虚拟仿真:开启无人机农林应用人才培养新路径
  • ELK 9.2.0 安装部署手册
  • 代码统计网站wordpress设置在新页面打开空白
  • 网站开发的流程 知乎设计培训网站建设
  • Qt 的字节序转换
  • QT Quick QML项目音乐播放器17----自定义Notification通知、请求错误提示、Loading加载中提示
  • 【Qt】AddressSanitizer 简介
  • Linux(麒麟)服务器离线安装单机Milvus向量库
  • Qt Widgets和Qt Qucik在开发工控触摸程序的选择
  • 毕业设计网站做几个图片设计素材
  • 网站设计计划深圳分销网站设计公司
  • word套打工具根据高度动态分页
  • 华清远见25072班单片机基础学习day3
  • docker安装Kubernetes
  • 湖科大教书匠每日一题(09.06~09.17)
  • HT71778:便携式音频设备的高效升压转换核心
  • 适合代码新手做的网站深圳市保障性住房申请官网
  • git的命令操作手册
  • 直播录制工具(支持 40 + 平台批量录制与自动监控)
  • 国际品牌的广州网站建设派代网
  • 商城网站开发实训报告外加工订单网
  • 6、Python中的异常处理
  • DNS配置作业
  • C++11:lambda表达式,包装器
  • 方圆网 网站建设营销策略包括哪些内容