二叉树的核心技术与C++实现:存储、遍历与递归应用

目录

一、二叉树基础概念与常见类型

1.1 二叉树核心概念

1.2 四种常见二叉树类型

类型1:满二叉树

类型2:完全二叉树

类型3:二叉搜索树(BST)

类型4:平衡二叉树(AVL)

类型5:退化二叉树

二、二叉树的存储方法

2.1 链式存储法(主流方法)

2.2 顺序存储法(数组实现)

2.3 极简存储法(隐式结构)

三、二叉树遍历与递归应用

3.1 三种基础遍历方式(递归实现)

前序遍历:根节点 -> 左子树 -> 右子树

中序遍历:左子树 -> 根节点 -> 右子树

后序遍历:左子树 -> 右子树 -> 根节点

3.2 递归应用实战

示例1:计算树的高度

示例2:查找节点是否存在

四、关键知识点总结

扩展学习路线:


        二叉树是一种层次化的、高度组织性的数据结构。二叉树的形态使得它有天然的优势,在二叉树上做查询、插入、删除、修改、区间等操作极为高效,基于二叉树的算法也很容易实现高效率的计算。

一、二叉树基础概念与常见类型

1.1 二叉树核心概念

定义:每个节点最多有两个子节点的树结构
特性

  • 每个节点有0/1/2个子节点

  • 左子树和右子树有严格顺序

  • 空树是有效二叉树(递归算法基例)

重要术语

  • 根节点(Root):最顶层的唯一节点

  • 叶子节点(Leaf):没有子节点的节点

  • 深度(Depth):根到当前节点的路径长度

  • 高度(Height):节点到最远叶子的路径长度


1.2 四种常见二叉树类型

类型1:满二叉树

定义:所有非叶子节点都有两个子节点,所有叶子在同一层
应用场景:完美平衡结构,用于最优搜索场景

// 满二叉树节点定义(每个节点必须有两个子节点或为叶子)
struct FullTreeNode {int val;FullTreeNode* left;  // 必须存在或为nullptrFullTreeNode* right; // 必须存在或为nullptrFullTreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

类型2:完全二叉树

定义:除最后一层外全满,最后一层节点左对齐
特性:适合数组存储,堆结构的基础

// 完全二叉树的数组实现(层次存储)
class CompleteBinaryTree {
private:vector<int> tree;  // 使用数组存储节点值
public:// 插入操作:按层序填充(自动计算父子关系)void insert(int val) {tree.push_back(val);}// 获取父节点索引公式:(i-1)/2 (i从0开始)int getParent(int childIndex) {return (childIndex - 1) / 2;}
};

类型3:二叉搜索树(BST)

定义:左子树所有节点值 < 根值 < 右子树所有节点值
优势:查找/插入/删除时间复杂度O(log n)

// BST基本操作实现
class BST {
private:struct Node {int val;Node *left, *right;Node(int v) : val(v), left(nullptr), right(nullptr) {}};Node* root = nullptr;public:// 插入操作(递归实现)Node* insert(Node* node, int val) {if (!node) return new Node(val);if (val < node->val) node->left = insert(node->left, val);elsenode->right = insert(node->right, val);return node;}
};

类型4:平衡二叉树(AVL)

定义:任意节点左右子树高度差绝对值≤1
平衡操作:通过旋转(左旋/右旋)维持平衡

// AVL树核心代码框架
class AVLTree {
private:struct Node {int val;int height; // 节点高度Node *left, *right;Node(int v) : val(v), height(1), left(nullptr), right(nullptr) {}};// 获取节点高度(处理空指针)int getHeight(Node* node) {return node ? node->height : 0;}// 右旋转操作(解决LL型不平衡)Node* rightRotate(Node* y) {Node* x = y->left;Node* T2 = x->right;x->right = y;y->left = T2;// 更新高度y->height = max(getHeight(y->left), getHeight(y->right)) + 1;x->height = max(getHeight(x->left), getHeight(x->right)) + 1;return x;}// 其他旋转操作类似(代码略)
};

类型5:退化二叉树

定义:每个节点只有一个子节点,退化为链表结构
特性

  • 失去二叉树的分支优势

  • 时间复杂度退化为O(n)

  • 常见于不平衡的二叉搜索树

    // 退化二叉树的示例(类似链表)
    struct DegenerateTreeNode {int val;DegenerateTreeNode* child; // 只有一个子节点DegenerateTreeNode(int x) : val(x), child(nullptr) {}
    };// 创建退化二叉树(类似链表)
    DegenerateTreeNode* buildDegenerateTree() {DegenerateTreeNode* root = new DegenerateTreeNode(1);root->child = new DegenerateTreeNode(2);root->child->child = new DegenerateTreeNode(3);return root;
    }

二、二叉树的存储方法

2.1 链式存储法(主流方法)

原理:通过指针连接节点,动态分配内存
优点:灵活处理非完全二叉树
缺点:指针占用额外空间

// 链式节点定义
struct LinkedNode {int val;LinkedNode* left;LinkedNode* right;LinkedNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 创建示例树
LinkedNode* buildDemoTree() {LinkedNode* root = new LinkedNode(1);       // 根root->left = new LinkedNode(2);            // 左子root->right = new LinkedNode(3);           // 右子root->left->left = new LinkedNode(4);      // 左子的左子return root;
}

2.2 顺序存储法(数组实现)

原理:按层序存储到数组,空位填充特殊值
适用场景:完全二叉树
优势:无需指针,父子关系通过索引计算

// 数组存储实现类
class ArrayTree {
private:vector<int> data;      // 存储节点值const int EMPTY = -1;  // 空节点标记值public:// 插入节点(自动扩展数组)void insert(int val, bool isNodeExist = true) {data.push_back(isNodeExist ? val : EMPTY);}// 获取左子节点索引:2*i + 1int getLeftChild(int index) {int left = 2 * index + 1;return (left < data.size() && data[left] != EMPTY) ? left : -1;}// 获取右子节点索引:2*i + 2int getRightChild(int index) {int right = 2 * index + 2;return (right < data.size() && data[right] != EMPTY) ? right : -1;}
};

2.3 极简存储法(隐式结构)

原理:仅存储节点值,通过索引规则隐式维护结构
典型应用:二叉堆存储
示例[1,2,3,4] 表示:

索引规则

  • 父节点索引 = (子节点索引-1)/2

  • 左子节点 = 2*父索引 + 1

  • 右子节点 = 2*父索引 + 2


三、二叉树遍历与递归应用

3.1 三种基础遍历方式(递归实现)

前序遍历:根节点 -> 左子树 -> 右子树

void preOrderTraversal(LinkedNode* root) {if (!root) return;  // 递归终止条件cout << root->val << " ";  // 先访问根节点preOrderTraversal(root->left);preOrderTraversal(root->right);
}
/* 示例树输出:1 2 4 3 */

中序遍历:左子树 -> 根节点 -> 右子树

void inOrderTraversal(LinkedNode* root) {if (!root) return;inOrderTraversal(root->left);cout << root->val << " ";  // 中间访问根节点inOrderTraversal(root->right);
}
/* BST中序遍历会得到有序序列 */

后序遍历:左子树 -> 右子树 -> 根节点

void postOrderTraversal(LinkedNode* root) {if (!root) return;postOrderTraversal(root->left);postOrderTraversal(root->right);cout << root->val << " ";  // 最后访问根节点
}
/* 常用于内存释放操作 */

3.2 递归应用实战

示例1:计算树的高度

int treeHeight(LinkedNode* root) {if (!root) return 0;  // 空树高度为0int leftHeight = treeHeight(root->left);    // 左子树高度int rightHeight = treeHeight(root->right);  // 右子树高度return max(leftHeight, rightHeight) + 1;  // 当前层+最大子树高度
}

示例2:查找节点是否存在

bool searchNode(LinkedNode* root, int target) {if (!root) return false;  // 终止条件1:未找到if (root->val == target) return true;           // 终止条件2:找到目标// 递归搜索左右子树return searchNode(root->left, target) || searchNode(root->right, target);
}

四、关键知识点总结

特性说明
时间复杂度平衡树操作O(log n),退化为链表时O(n)
空间复杂度链式存储O(n),数组存储可能浪费空间
递归优势自然映射树的分支结构,代码简洁
存储选择原则动态操作选链式,完全二叉树用数组

扩展学习路线

  1. 线索二叉树:利用空指针优化遍历

  2. 红黑树:工程中最常用的平衡树

  3. 哈夫曼树:数据压缩核心结构

  4. B+树:数据库索引标准结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/26757.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《白帽子讲 Web 安全:点击劫持》

目录 摘要&#xff1a; 一、点击劫持概述 二、点击劫持的实现示例&#xff1a;诱导用户收藏指定淘宝商品 案例 构建恶意页面&#xff1a; 设置绝对定位和z - index&#xff1a; 控制透明度&#xff1a; 三、其他相关攻击技术 3.1图片覆盖攻击与 XSIO 3.2拖拽劫持与数据…

IDEA 使用codeGPT+deepseek

一、环境准备 1、IDEA 版本要求 安装之前确保 IDEA 处于 2023.x 及以上的较新版本。 2、Python 环境 安装 Python 3.8 或更高版本 为了确保 DeepSeek 助手能够顺利运行&#xff0c;您需要在操作系统中预先配置 Python 环境。具体来说&#xff0c;您需要安装 Python 3.8 或更高…

Linux:进程替换

目录 进程程序替换 替换原理 进程替换相关函数 环境变量与进程替换函数 命令行解释器(my_xshell) 进程程序替换 上一篇进程控制讲到&#xff0c;父进程创建子进程就是为了让子进程去做一些另外的事情&#xff0c;但是不管怎么说&#xff0c;子进程的部分代码也还是父进程…

Navicat连接虚拟机数据库详细教程

Navicat连接虚拟机数据库详细教程 以Windows主机 上的navicat 连接ubuntu虚拟机为例 确认虚拟机ip地址和主机ip地址 主机地址查询 cmd输入ipconfig 登录mysql 创建用户 CREATE USER newuserlocalhost IDENTIFIED BY password; CREATE USER newuser% IDENTIFIED BY passwor…

Java内存管理与性能优化实践

Java内存管理与性能优化实践 Java作为一种广泛使用的编程语言&#xff0c;其内存管理和性能优化是开发者在日常工作中需要深入了解的重要内容。Java的内存管理机制借助于垃圾回收&#xff08;GC&#xff09;来自动处理内存的分配和释放&#xff0c;但要实现高效的内存管理和优…

解码中国AI双雄突围:DeepSeek破壁与英伟达反攻背后的算力暗战

一、算力困局下的中国突围术 2024年夏季的科技界暗流涌动&#xff1a;北京中关村的服务器机房里&#xff0c;寒武纪最新MLU300X芯片正以每秒120万亿次运算支撑着自动驾驶系统的实时决策&#xff1b;上海张江的AI实验室中&#xff0c;DeepSeek团队通过神经元分块技术将模型参数压…

【Python · Pytorch】Conda介绍 DGL-cuda安装

本文仅涉及DGL库介绍与cuda配置&#xff0c;不包含神经网络及其训练测试。 起因&#xff1a;博主电脑安装了 CUDA 12.4 版本&#xff0c;但DGL疑似没有版本支持该CUDA版本。随即想到可利用Conda创建CUDA12.1版本的虚拟环境。 1. Conda环境 1.1 Conda环境简介 Conda&#xff1…

0x03 http协议和分层架构

HTTP协议 简介 Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则 http协议基于TCP协议&#xff1a;面向连接&#xff0c;安全基于请求-响应模型&#xff1a;一次请求对应一次响应HTTP协议是无状态的协议&#xff…

IDEAPyCharm安装ProxyAI(CodeGPT)插件连接DeepSeek-R1教程

背景&#xff1a;最近DeepSeek比较火嘛&#xff0c;然后在githup上也看到了GitHub Copilot&#xff0c;就想着现在AI的准确率已经可以提高工作效率了。所以从网上找了一些编程插件&#xff0c;发现Proxy支持的模型比较多&#xff0c;通用性和适配性比较好。所以本文记录一下pro…

qt-C++笔记之QToolButton和QPushButton的区别

qt-C笔记之QToolButton和QPushButton的区别 code review! 文章目录 qt-C笔记之QToolButton和QPushButton的区别1.运行2.main.cpp3.main.pro 1.运行 QToolButton 适用于工具栏或需要较紧凑、图标化显示的场合。通过 setAutoRaise(true) 与 setToolButtonStyle(Qt::ToolButtonTe…

css的元素显示模式

一.什么是元素显示模式 作用&#xff1a;网页的标签非常多&#xff0c;不同地方会用到不同类型的标签&#xff0c;了解他们的特点可以更好的布局我们的网页。 元素显示模式就是元素(标签)以什么方式进行显示&#xff0c;比如<div>自己占一行&#xff0c;比如一行可以放多…

MySQL整体架构

目录 1 客户端 2 服务端 2.1 Server层 2.1.1 连接器 2.1.2 查询缓存 2.1.3 词法器 2.1.4 优化器 2.1.5 执行器 2.2 存储引擎层 1 客户端 ● 客户端为连接MySQL服务端的工具或者驱动&#xff0c;比如JDCB&#xff0c;ODBC等等 ● 用于连接目前服务器&#xff0c;并且发送需要执行…

【踩坑随笔】`npm list axios echarts`查看npm依赖包报错

npm list axios echarts查看npm依赖包出现以下报错&#xff0c;原因就是包的版本匹配问题&#xff0c;按照提示降axios版本或者自己升找合适的got版本&#xff0c;我这里是选择了降版本。本文记录仅做解决思路参考不一定适配大家的实际情况。 weed-detection-system1.0.0 E:\P…

大唐杯——阶段二01

03 5G寻呼 UE&#xff08;User Equipment&#xff09; UE是用户设备&#xff08;User Equipment&#xff09;的缩写&#xff0c;指的是移动通信网络中的终端设备&#xff0c;例如手机、平板电脑、物联网传感器等。 AMF&#xff08;Access and Mobility Management Function&a…

小程序画带圆角的圆形进度条

老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…

SimVS: Simulating World Inconsistencies for Robust View Synthesis 论文解读

目录 一、概述 二、相关工作 三、SimVS 1、利用视频模型模拟世界的不一致性 2、效果 一、概述 该论文提出了一种名为SimVS的视频模型方法&#xff0c;旨在解决稀疏多视角图像捕捉中因动态变化&#xff08;光照变化、物体运动&#xff09;导致的视图合成鲁棒性问题。 动机&a…

华为OD机试真题:跳房子I (E卷、Java)

华为OD机试&#xff08;E卷D卷C卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 跳房子&#xff0c;也叫跳飞机&#xff0c;是一种世界性的儿童游戏。 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格。跳房子的过程中&#xff0c;可以向前跳&…

快速排序算法详解

算法原理 快速排序是一种分治的策略的排序算法。它的核心排序思想是将问题不断的分解为子问题。以数组为例进行介绍更容易理解&#xff0c;创建一个数组或者vector&#xff0c;假设是std::vector<int> a{3&#xff0c;2, 1, 5, 4,7}&#xff0c;要对a从小到大进行排序&a…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的电脑本地部署一下DeepSeek试试&#xff0c;由于不希望污染电脑的Windows环境&#xff0c;所以在wsl中安装了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安装了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

题解 | 牛客周赛82 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 判断字符串第一个字符和第三个字符是否相等 import java.io.*; import java.math.*; import java.u…