- 博客(66)
- 收藏
- 关注
原创 Set 和 Map 深入详解及其区别
C++ STL中的关联式容器(map/set)基于红黑树实现,存储有序元素。map存储键值对,支持快速查找和修改;set存储唯一值,用于去重和集合运算。两者都提供O(logn)的插入、删除和查找操作,支持自定义比较函数。multimap和multiset允许键重复。主要区别在于map维护键值映射关系,set仅维护值集合。这些容器在需要有序存储和快速查找的场景中非常高效。
2025-12-20 16:59:10
619
原创 二叉树最近公共祖先(LCA)问题详解
本文介绍了二叉树中寻找两个节点最近公共祖先(LCA)的两种方法。递归方法通过深度优先搜索,判断节点在左右子树中的分布情况来定位LCA,时间复杂度为O(n)。非递归方法使用父指针映射,将问题转化为链表相交问题,通过建立父节点关系表和回溯路径来查找LCA。两种方法各有特点,递归简洁但可能栈溢出,非递归更稳定但需要额外空间存储父节点信息。
2025-12-10 00:46:36
930
原创 【数据结构】二叉搜索树
本文介绍了二叉搜索树的基本操作,包括查找、插入和删除节点的方法。文章还给出了C++实现代码,包含节点类模板和二叉搜索树类模板,演示了插入、查找、删除和中序遍历等核心功能。
2025-12-05 00:02:31
394
原创 【C++】多态与虚函数
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了 Person。Person对象买票全价,Student对象买票半价。必须通过基类的指针或者引用调用虚函数被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
2025-12-03 19:24:17
884
原创 C++继承详解
摘要:继承是面向对象编程中实现代码复用的重要机制,允许派生类在基类基础上扩展功能。文章详细介绍了三种继承方式(公有、保护、私有)的特点及访问权限变化,阐述了基类与派生类间的对象赋值转换规则。同时分析了继承体系中的作用域规则、派生类成员函数特性,以及友元关系的不可继承性。针对复杂的菱形继承问题,提出了虚继承解决方案。最后对比了函数重载、隐藏和覆盖三者的区别,重点说明了虚函数实现多态性的原理。全文系统性地讲解了继承机制的核心概念及其应用场景。
2025-12-02 18:37:35
773
原创 【C++STL】List详解
list是C++的一个序列容器,允许在序列中的任意位置进行常数时间的插入和删除操作,并支持双向迭代。列表容器采用双向链表实现,与其他基本标准序列容器(数组、向量和双端队列)相比,列表在插入、提取和移动容器内已获得迭代器的任何位置的元素方面通常表现更好,主要缺点是它们无法通过位置直接访问元素
2025-11-25 02:40:30
977
原创 【C++STL】vector详解
本文介绍了C++ STL中的vector容器,包括其基本概念、内存模型及常用接口。vector作为动态数组,支持快速随机访问和自动扩容,但中间插入/删除操作效率较低。详细讲解了vector的初始化、遍历(operator[]、at()、迭代器)、空间管理(resize/reserve)以及增删查改操作(push_back/pop_back/find/insert/erase/swap)。特别强调了迭代器失效规则和不同编译器的扩容策略差异。vector适合需要频繁随机访问和尾部操作的场景。
2025-11-20 08:00:00
997
原创 C++模板初阶
摘要:C++泛型编程通过模板实现代码复用,包括函数模板和类模板。函数模板允许编写与类型无关的通用函数,编译器根据调用时的实参类型自动实例化具体版本。函数模板支持隐式和显式实例化,遵循精确匹配优先的规则。类模板则用于创建通用数据结构,实例化时需要显式指定类型参数。泛型编程减少了代码重复,提高了可维护性,是C++重要编程范式。
2025-10-15 15:52:59
1081
原创 C/C++内存管理(new,delete)
本文深入探讨了C/C++内存管理与动态分配机制。主要内容包括:1) C/C++程序内存划分为代码区、全局/静态区、栈区、堆区和常量区;2) C语言通过malloc/calloc/realloc/free管理动态内存;3) C++引入new/delete运算符,对内置类型只管理内存,对自定义类型还处理构造/析构函数;4) 底层通过operator new/delete函数实现,分别封装malloc/free;5) 定位new表达式可在指定内存位置构造对象;6) 比较了malloc/free与new/delet
2025-10-14 20:58:26
744
原创 类与对象(下)
本文摘要: 本文深入探讨了C++中的构造函数初始化列表、隐式类型转换、static成员、友元和匿名对象等核心概念。重点内容包括:1) 初始化列表的使用场景和重要性,特别是const成员、引用成员和继承情况下的必要性;2) 隐式类型转换的机制及优缺点,强调推荐使用explicit避免潜在问题;3) static成员的特性及其定义方式;4) 友元机制的工作原理及其对封装性的影响;5) 匿名对象的定义、生命周期和应用场景。文章通过大量代码示例详细解析了这些特性的正确使用方式及其潜在风险,为深入理解C++面向对象编
2025-10-10 17:35:40
745
原创 类与对象(中)
这篇文章介绍了C++类的6个默认成员函数及其特性。主要内容包括:1)构造函数用于对象初始化,支持重载;2)析构函数负责资源清理,在对象生命周期结束时自动调用;3)拷贝构造函数创建对象副本,默认实现浅拷贝;4)运算符重载允许自定义类型运算符行为;5)const成员函数修饰this指针,限制成员修改;6)取地址运算符重载通常不需要自定义实现。文章重点说明了何时需要自定义这些成员函数,特别是当类管理动态资源时需要自定义析构函数和拷贝构造函数。
2025-10-09 18:28:28
1003
原创 C++运算符重载
本文介绍了C++运算符重载的基本概念和实现方法。运算符重载允许为自定义类型定义运算符行为,增强代码可读性。文章详细讲解了可重载的运算符类型、基本语法规范,以及不可重载的运算符。通过日期类Date的示例,展示了赋值运算符、比较运算符、算术运算符、自增运算符和流操作符等常见运算符的重载实现技巧,包括参数处理、返回值优化和特殊情况处理等关键点。最后强调了运算符重载的注意事项和最佳实践。
2025-10-09 18:19:15
1035
原创 类与对象(上)
本文系统介绍了C++面向对象编程的核心概念。主要内容包括:1)面向过程与面向对象的区别;2)类的引入与两种定义方式;3)访问限定符(public/private/protected)及其封装特性;4)类的实例化过程;5)类对象大小的计算规则;6)成员函数的this指针及其应用场景。重点阐述了C++通过类将数据与操作封装在一起,利用访问控制实现信息隐藏的特性,以及this指针在成员函数中的重要作用。这些概念构成了C++面向对象编程的基础框架。
2025-09-29 18:25:44
1207
原创 C++引用
在 C++ 中,引用(Reference)是一种为变量或对象起别名的方式,它提供了对现有数据的间接访问。引用是 C++ 区别于 C 语言的重要特性之一,设计初衷是提高代码的安全性和可读性,同时避免指针的复杂性。在生活中,我们可能也会给一些同学起外号,以“张三”同学为例,我们可以叫他“啊三”,当我们叫到这个外号的时候就会自然而然的想到“张三”同学,”啊三”就是张三的别名。在语法层面上看,引用就是取别名引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它与引用的变量。
2025-02-25 20:10:20
409
1
原创 C++函数重载,C不支持函数重载的原因
C++ 中的函数重载(Function Overloading)允许在同一作用域内定义多个同名函数,但这些函数的参数列表必须不同(参数的类型、数量或顺序不同)。函数重载的目的是让函数名更具语义化,同时处理不同类型或数量的参数。
2025-02-25 19:38:53
744
原创 C++缺省参数
在C++中,缺省参数(Default Arguments)允许在函数声明时为参数指定默认值。当调用函数时,若未显式提供该参数的值,则自动使用默认值。缺省参数可以简化函数调用,并为函数提供更灵活的用法。
2025-02-24 20:02:30
397
原创 C++命名空间域
在C++中,命名空间(Namespace)是一种用于组织代码、避免命名冲突的机制,而“命名空间域”可以理解为命名空间的作用域,即在命名空间内定义的标识符(如变量、函数、类等)的可见性和访问范围。
2025-02-24 19:29:22
685
原创 【数据结构】排序详解(希尔排序,快速排序,堆排序,插入排序,选择排序,冒泡排序)
元素集合越接近有序,直接插入排序算法的时间效率越高时间复杂度:O(N^2)空间复杂度:O(1),它是一种稳定的排序算法4.稳定性:稳定希尔排序是对直接插入排序的优化当gap>1时都是预排序,目的是让数组更接近有序。当gap==1时,数组已经接近有序,这样排序就会很快。这样整体而言,可以达到优化的效果希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在不同书上给出的希尔排序的时间复杂度都不一样冒泡排序是一种非常容易理解的排序时间复杂度:O(N^2)
2024-05-21 16:55:25
1149
1
原创 【数据结构】快速排序(详解)
在待排序的序列中,选择一个元素作为基准元素(key)。这个元素可以是序列的第一个元素、最后一个元素或者任意一个元素,甚至是随机选取的一个元素。:从序列的一端开始(可以是左端或右端),将遇到的第一个比基准元素小(或大)的元素填入坑中,并形成一个新的坑。在非递归版本中,我们使用栈(或队列)来保存待排序的子数组的起始和结束索引,而不是直接递归调用;:一个记录序列的开始的下标(left),另一个记录序列的末尾的下标(right)。:此时,基准值左边的所有元素都比基准值小,基准值右边的所有元素都比基准值大。
2024-05-21 16:53:45
1341
原创 【数据结构】单链表逆置(详解)————四种方法
逆置就是把最后一个数据提到最前面,倒数第二个放到第二个……依次类推,直到第一个到最后一个。由于链表没有下标,所以不能借助下标来实行数据的逆置,要靠空间的转移来完成链表的逆置,这里采用没有头节点的链表来实现逆置。
2024-05-17 18:38:39
2175
2
原创 树的概念与结构(详解)
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一颗倒挂的树,也就是说它是根朝上,而叶朝下的。有一个特殊的结点,称为根结点,根节点没有前驱结点除根节点外,其余结点被分为M(M>0)个互不相交的集合T1,T2,......,Tm,其中每个集合Ti(1<=i<=m)又是一颗结构与树类似的子树。每颗子树的根节点有且只有一个前驱结点,可以由0个或多个后继结点因此,树是递归定义的注意:树形结构中,子树之间不能有交集,否则就不是树形结构。
2024-05-17 13:43:07
1269
原创 二叉树OJ题解2(相同二叉树,对称二叉树)
若不相同则两个二叉树一定不同,若相同,再分别判断两个二叉树的左子树是否相同以及右子树是否相同。这是一个递归的过程,因此可以使用深度优先搜索,递归地判断两个二叉树是否相同。如果一个树的左子树与右子树镜像对称,那么这个树是对称的。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。如果两个二叉树都不为空:(那么首先判断它们的根节点的值是否相同)如果两个二叉树中有且只有一个为空:则两个二叉树一定不相同。每个树的右子树都与另一个树的左子树镜像对称。如果两个二叉树都为空:则两个二叉树相同。
2024-05-04 13:41:28
331
原创 二叉树的实现(详解,数据结构)
设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。二叉树的存储类似链表,可以由前面的结点找到后面的结点,因此二叉树的销毁也是由后向前销毁会方便很多,所以我们。的知识,就是先将根结点入队,判断队列是否为空,循环将队首元素出队的同时队首元素子节结点入队。根据完全二叉树的定义,具有n个结点的完全二叉树与满二叉树中编号从1~n的结点一一对应。
2024-05-04 13:25:44
1241
原创 二叉树oj题解1(最大深度,单值二叉树)
一棵树的所有节点都有相同的值,当且仅当对于树上的每一条边的两个端点,它们都有相同的值(这样根据传递性,所有节点都有相同的值)。因此,我们先检查节点和子节点是否相同,后使用分治的实现,检查左右子树是否是单值二叉树,是返回true,否返回false;如果我们知道了左子树和右子树的最大深度 len1 和 len2,那么该二叉树的最大深度即为。如果二叉树每个节点都具有相同的值,那么该二叉树就是。为根节点到最远叶子节点的最长路径上的节点数。只有给定的树是单值二叉树时,才返回 true。使用分治的思想来实现计算。
2024-04-30 20:34:02
257
原创 浅谈TopK问题(堆的应用,文件处理,堆排序)
这些排序方法就不适用了,就比如当数据到达10亿时,再使用冒泡排序,它的时间复杂度就相当恐怖了,这时我们就要用到。,如果我们按上述操作对堆顶元素进行替换,那么也只能不断更新这个最大值,我们能使用的方法有很多,就比如比较简单的冒泡排序,他的时间复杂度是。的性质来满足我们的TopK了,这时它的时间复杂度是。在文件data.txt中找出前K个最大的数据。,循环完成后小堆就剩下前K个最大的数据。堆实现思路:(前K个最大的数据)找出最大或最小的前K个数据。找最大建小堆,找最小建大堆。个数据建大小为K的小堆。
2024-04-30 17:25:32
665
原创 [Leetcode]用栈实现队列
int size;}Stack;//创建栈return tmp;//入栈exit;//出栈exit;return s;//栈的销毁free(tmp);tmp = NULL;
2024-04-18 13:38:36
560
原创 [Leetcode]用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop和empty实现MyStackint pop()int top()truefalse。
2024-04-18 13:17:38
766
原创 设计循环队列(队列oj)
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。// 返回 false,队列已满。// 返回 true。// 返回 true。// 返回 true。// 返回 true。// 返回 true。// 返回 true。思路:数组,构造大小为K+1的数组,(
2024-04-17 11:14:52
909
原创 队列的解释和实现
队列(Queue)是一种特殊的线性数据结构,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。队列中没有元素时,称为空队列。队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以又称为先进先出(FIFO—first in first out)线性表。
2024-04-17 10:58:41
577
原创 栈的解释和实现
栈(Stack)是一种遵循后进先出()原则的数据结构。在栈中,元素的添加和移除都发生在同一端,这一端通常被称为栈顶(Top)。栈底(Bottom)是栈的另一端,通常元素不会从栈底添加或移除。
2024-04-16 16:21:28
562
原创 【id:21】【20分】E. 抄袭查找(结构体+指针+函数)
定义一个函数,返回值为一个整数,参数是两个结构体指针,函数操作是比较两张试卷的每道题目的答案,如果相同题号的答案相似度超过90%,那么就认为有抄袭,函数返回抄袭题号,否则返回0。相似度是指在同一题目中,两个答案的逐个位置上的字符两两比较,相同的数量大于等于任一个答案的长度的90%,就认为抄袭。每张试卷包含:学号(整数类型)、题目1答案(字符串类型)、题目2答案(字符串类型)、题目3答案(字符串类型)在一行中,把发现抄袭的两个学号和题目号输出,只输出第一次发现抄袭的题号,数据之间用单个空格隔开。
2024-03-21 22:35:57
433
5
原创 顺序表和链表的比较(详解)
顺序表和链表都属于线性表,逻辑上是线性结构,但是物理结构上,顺序表物理结构是(内存空间)连续的,而链表不是(内存空间)连续的这样的结构差异就造成了顺序表支持按下标访问元素,而链表就不支持相反链表也有优点,在从头插入元素时,链表会比顺序表方便很多,因为在头插过程中,顺序表需要将后面的元素都向后挪一位,而链表仅需简单插入即可。
2024-03-21 16:32:14
496
原创 【id:10】【20分】D. 三串合一(指针与字符数组)
连续三行,每行输入数字a和b,表示每个子串的开始和结束位置。注意字符串的位置是按照一般意义从1开始计算,和编程中的数组位置不同。例如字符串abcdefg,开始位置是3,结束位置是5,那么子串就是cde。3. 使用动态数组的方法创建新的字符串,并且使用指针读取三个字符串的不同部分,并且复制到新字符串中,要求整个过程都不能使用数组下标。输入三个字符串,通过指针读取各个字符串的子串(子串是指字符串中连续的一小部分),把它们合并成一个新字符串。2. 输入后,根据三个字符串的子串的长度,计算出新字符串的长度。
2024-03-20 21:31:49
244
原创 【C语言】实现通讯录(详解)
为了方便后期的处理数组大小,所以我们可以利用宏来实现这个功能#define NAME_MAX 100//联系人姓名最大长度#define ADDR_MAX 100//联系人地址最大长度#define GENDER_MAX 10//联系人性别最大长度#define TELE_MAX 12//联系人电话号码最大长度2.0功能分化(
2024-03-20 21:27:52
564
原创 atoi函数详解
1、该函数首先会丢弃尽可能多的空白字符,直到找到第一个非空白字符,然后,从这个字符开始,取一个可选的初识加号或者减号,后跟尽可能多的十进制数字,并将他们返回一个int类型的数值。2、若该字符串是在整数的字符后包含其他字符,则这些字符将会被忽略,返回其他字符之前的整数,并且不会对该函数造成任何影响。3、若该字符串中第一个非空字符序列表示有效的整数,或是一个空指针,或只包含空白字符,则不执行任何转换,并且返回零。注意:该函数的返回值为int类型的整数,转换后的值不可超出int可表示的范围。
2024-01-26 20:29:25
549
原创 浮点数在内存中存储
对于64位浮点数(双精度浮点数),最高的1位存储符号位S,接着11位存储指数E,剩下的52位存储有效数字M。对于32位浮点数(单精度浮点数),最高的1位存储符号位S,接着8位存储指数E,剩下的23位存储有效数字M。1. (-1)^S表示符号位,当S=0,V为正数,当S=1,V为负数。同理,十进制的-5.0,可以表示为S=1,M=1.01,E=2。那么,根据上面V的格式,可以得出S=0,M=1.01,E=2。2. M表示有效数字,M是大于等于1,小于2的。整数的存储方式和浮点数的存储方式是不一样的。
2024-01-26 18:31:16
671
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅