登录社区云,与社区用户共同成长
邀请您加入社区
在学习红黑树之前,我们首先需要知道它到底解决了什么问题。4/ \2 6/ \ / \1 3 5 7log₂NO(logN)但是普通二叉搜索树并不会主动维护自己的结构。12345O(N)O(N)所以我们需要一种能够自动控制高度的二叉搜索树。AVL 树是一种解决方法,而红黑树则是另一种非常经典的解决方案。红黑树并不像 AVL 树那样严格要求左右子树高度差不超过 1,而是通过一些颜色规则间接约束树的高度
红黑树为什么能够保持近似平衡?插入以后为什么需要变色和旋转?这一篇正式进入代码实现。1. 红黑树结点2. 左旋与右旋3. BST 插入4. 红黑树插入修复5. Find 查找6. 红黑树合法性验证红黑树的代码虽然看起来比较长,但真正复杂的部分其实只有插入修复。第一阶段:BST 插入第二阶段:新结点染红第三阶段:如果父结点为红,修复红红冲突→ 变色→ 向上继续→ 判断 LL / RR / LR /
左子树中的关键字小于根右子树中的关键字大于根左右子树仍然是二叉搜索树借助这个规则,我们可以根据关键字大小决定向左还是向右查找。但是,普通二叉搜索树有一个明显的问题:它只规定了关键字之间的大小关系,却没有限制树的形状。查找7O(log N)O(N)AVL 树就是为了解决这个问题而出现的。普通二叉搜索树↓树高决定操作效率↓限制左右子树高度差↓引入平衡因子↓按照 BST 规则插入↓沿祖先路径更新平衡因子
按照 BST 规则插入↓沿祖先路径更新平衡因子↓平衡因子为 0:停止平衡因子为 ±1:继续平衡因子为 ±2:旋转真正实现 AVL 树时,难点主要集中在旋转。二叉搜索树的大小关系左孩子指针右孩子指针父指针整棵树的根指针局部子树与上一层的连接结点的平衡因子右单旋左单旋左右双旋右左双旋最后给出一套可以直接在 Linux 环境中编译运行的完整 C++ 实现。假设失衡结点为parent说明 parent 左
在学习普通二叉树时,我们主要关注的是树的结构,以及前序、中序、后序、层序等遍历方式。但普通二叉树有一个问题:结点之间没有统一的大小关系。假设现在要在一棵普通二叉树中查找数字13,除了把整棵树遍历一遍,我们通常没有更好的办法。因为站在某个结点上时,并不知道目标应该在左子树还是右子树。较小的数据放在左边较大的数据放在右边正是这条看起来很简单的规则,让树具备了定向查找、插入和删除的能力。这时树的方向会与
int main()students.insert({1003, "张三"});students.insert({1001, "李四"});students.insert({1002, "王五"});return 0;
虽然ptr的类型是Base*编译器如何知道指针实际指向哪种对象?静态绑定和动态绑定有什么区别?什么是虚函数表和虚函数表指针?派生类重写虚函数后,虚表发生了什么变化?为什么含有虚函数的对象可能会变大?为什么构造和析构期间不会调用更派生类版本?如何保存一组不同类型的多态对象?应该在什么时候使用?虚函数会带来多大性能开销?本文主要从底层原理和实际工程使用两个角度,继续讲解 C++ 多态。对象保存虚表指针
继承解决了类之间的代码复用问题,但仅仅有继承,还不能让程序根据对象的实际类型自动执行不同的行为。普通人:全价买票学生:优惠买票军人:优先买票如果程序通过大量if-elsecout << "全价买票" << endl;cout << "优惠买票" << endl;cout << "优先买票" << endl;多态提供了一种更自然的方式:调用者只面向统一的基类接口,具体执行哪个版本,由对象的实际类型决
继承是 C++ 面向对象部分非常重要的一块内容。在学习继承之前,我们已经接触过函数复用、模板复用和 STL。它们解决的都是“相同代码不要重复写”的问题,而继承解决的是类层面的复用。例如,学生和老师都具有姓名、年龄、电话和地址,也都需要进行身份认证。如果分别在Student和Teacher中定义这些成员,不但代码重复,后续修改起来也比较麻烦。继承允许我们把公共部分抽取到一个基类中,再让不同的派生类在
在数据结构中,栈算是比较容易理解的一种结构。它的规则很简单:最后放进去的元素,最先被取出来。后进先出LIFOC++ STL 已经提供了stack,使用起来并不复杂。但只记住push()和pop()栈为什么只能访问栈顶?pop()为什么不返回被删除的元素?stack为什么没有迭代器?什么是容器适配器?为什么 STL 默认使用deque作为底层容器?如何用已有容器简单模拟一个栈?栈是一种操作受限的线性
set某个关键字是否存在?而实际开发中,我们经常不只是想找到一个关键字,还想找到它对应的信息。英文单词 -> 中文解释学号 -> 学生成绩商品编号 -> 库存数量用户名 -> 用户资料文件名 -> 文件大小这种“一个关键字对应一个值”的关系,称为映射关系。C++ STL 中的map就是用来保存这种关系的有序关联式容器。key :用于查找和排序value :与 key 关联的数据map和set的关系
本文介绍了一个基于C++的高性能内存池项目,其原型为Google的tcmalloc线程缓存分配器。文章首先解释了内存池的概念及其解决的问题(如内存碎片),然后详细讲解了如何设计一个定长内存池。内存池通过预申请大块内存并自主管理,显著提升了内存分配效率。核心实现包括:优先复用自由链表中的内存块,不足时从大块内存切分,并使用定位new在裸内存上构造对象。该项目旨在学习tcmalloc的核心思想,适用于
派生类构造时,基类部分由谁初始化?拷贝构造和赋值运算符是否需要处理基类?为什么构造顺序是从基类到派生类,析构顺序却正好相反?基类析构函数什么时候必须是虚函数?友元关系和静态成员会不会被继承?多继承为什么会产生二义性?菱形继承为什么会造成数据冗余?虚继承如何让多个路径共享同一个基类子对象?继承和组合到底应该如何选择?这些内容看起来比较分散,实际上都围绕一个核心问题:一个派生类对象中,不仅有派生类自己
C++ 的继承机制,初看就是"子类能访问父类的东西",但真到了同名隐藏、切片赋值、模板继承这些细节上,稍不注意就会写出 bug。别光看,一定要动手敲。把上面这些例子复制到 VS 里跑一遍,逐行设断点看调用栈,理解会深很多。
生活中排队是一件很常见的事。先到的人先接受服务,后到的人排在队尾等待。先进先出FIFOC++ STL 提供了queue容器适配器,可以直接实现队尾入队、队头出队。广度优先搜索二叉树层序遍历任务调度消息缓冲请求排队打印任务管理生产者和消费者模型本文从queue的基本接口开始,逐步讲解它的底层要求、典型应用、两个栈实现队列,以及一个简化版queue的模拟实现。队列是一种操作受限的线性数据结构。push
在 C++ STL 中,vector和list都是非常重要的序列式容器。如果说vector更像是“可以自动扩容的数组”,那么list更像是“一串用指针连接起来的节点”。很多同学刚学list的时候,会觉得它没有vector好用:不能下标访问,遍历起来还要用迭代器,看起来没有那么直观。但list适合频繁插入和删除插入时不会整体搬移元素删除某个节点时,通常只影响被删除节点对应的迭代器底层结构非常适合帮助
本文介绍了平衡二叉搜索树(AVL树)的概念与实现。首先回顾了二叉搜索树的特性及其可能退化为单支树的问题,进而引出AVL树通过旋转操作维持平衡的特性。重点讲解了AVL树的插入操作,包括平衡因子的更新规则和四种旋转方式(左单旋、右单旋、左右双旋、右左双旋),并提供了相关代码实现。最后介绍了验证AVL树平衡性的检测方法,通过递归计算子树高度差和检查平衡因子来确保树的正确性。文章旨在帮助读者深入理解AVL
相信学过 C++ 的朋友都接触过模板。入门阶段我们一般就写个这种最基础的函数模板,感觉"就是那种感觉"。但当你真的在项目里用起来,或者读到一些库的源码时,会发现模板远比你想象的复杂——非类型参数、全特化、偏特化、指针比较的坑……这些东西不亲自踩一遍,光看理论是很难真正理解的。
优先级队列这东西,刷力扣的同学肯定不陌生。默认是大顶堆,想要小顶堆得写成,麻烦得很。很多人只停留在"会用"的层面,至于它底层怎么实现的、那个到底是什么玩意,一问就卡壳。这篇文章就带你从零撸一个,顺便把仿函数(Functor)这层窗户纸捅破。代码不玩花活,确保你在任何老项目里都能直接抄。
《黑神话:悟空》辅助工具提供44项功能,覆盖生存续航、战斗强化、资源获取、探索优化五大维度,支持v1.0-1.0.20版本离线使用。包含无敌模式、属性修改、资源倍率、移速调整等实用功能,通过热键一键切换,有效降低开荒难度,提升探索效率。使用前建议备份存档,仅限单人模式。下载链接:黑神话悟空风灵月影修改器工具
什么时候用差分数组?只要题目出现**“频繁对一个区间进行加减操作”,且“最后才询问数组的最终状态”**,无脑用差分数组!差分和前缀和是好兄弟:差分是前缀和的逆运算。差分负责把ONO(N)ON的区间修改变成O1O(1)O1。前缀和负责最后扫尾,把差分数组还原成真实数据。因为我们要操作,所以初始化差分数组时,大小一定要比题目给定的最大范围多加 2,避免。差分数组属于离线算法。也就是说,你必须把所有的“
重点就是仿函数和堆结构的实现
/ 函数声明// 函数定义// 函数调用private:public:// 构造函数// 成员函数// 使用类。
本文针对《EA SPORTS FC 26》启动后卡在 Starting EA Javelin AntiCheat 界面并直接退回 EA App 的常见问题,整理了包含官方方案与社区高频反馈的全套排障文档。本文涵盖从软件冲突、反作弊服务重建到系统底层设置的完整解决方案。
在满足指定条件的前提下,重复执行一段代码块的语法结构,直到条件不成立时终止循环,避免重复编写代码,提升程序效率。在一个循环内部,嵌套另一个完整的循环,外层循环每执行一次,内层循环执行完整的所有次数。C语言三大循环是编程基础,熟练掌握执行逻辑、适用场景、控制语句,是写出高效代码的关键。1. for循环:固定次数首选,语法简洁;2. while循环:未知次数首选,先判断后执行;3. do-while循
一、注册 iKuuu备用域名信息:(
摘要: Origin 2025是一款功能强大的科研数据分析与绘图软件,支持多种数据格式导入和高级分析处理。本文提供了详细的安装教程:下载压缩包后解压,运行安装程序并按步骤配置(包括序列号输入、安装路径修改等),最后通过替换授权文件完成破解。教程包含21个图文步骤,涵盖软件安装、许可证配置及语言设置等关键环节,帮助用户顺利完成Origin 2025的永久免费版安装。适用于科研人员及学生进行数据可视化
本文分析了C++17引入的std::clamp函数,探讨其在边界值限制方面的应用与陷阱。文章首先指出C++17前开发者需通过嵌套std::min/max或自定义宏实现边界限制,这些方法存在认知负担和安全隐患。随后详细介绍了std::clamp的语法、实现原理及工程应用场景,包括图形渲染和游戏开发。最后重点警示了三个使用陷阱:未定义行为(当lo>hi时)、悬空引用风险以及浮点数NaN问题,并给
本文深入探讨C++17引入的std::any类型,分析其作为类型安全的void替代方案的技术原理与工程实践。通过对比传统void的缺陷,阐述了std::any如何通过类型擦除和小对象优化机制实现安全存储任意类型数据,同时自动管理内存生命周期。文章详细解析了std::any_cast的安全提取范式,并指出其适用于插件系统、属性字典等需要存储未知类型的场景。最后强调工程实践中应根据类型确定性在std:
class 类模板名// 类内成员定义// 类模版public:_size = 0;// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误,具体原因后面会讲// 扩容++_size;
代码复用就是“
顺序表链表经典算法
编译器生成的构造函数会去。
对象是类的具体实例。当你根据“蓝图”(类)真正制造出一个“建筑”时,这个建筑就是一个对象,对象是存在于内存中的,你可以操作它class为定义类的关键字,name为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省 略,类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或 者成员函数• 为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面
(又称)是指在函数声明或定义时为形参指定一个默认值,当调用函数时,如果调用者没有提供该参数的实际值,编译器会自动使用预先设定的默认值。
单链表—很细讲解