- 博客(47)
- 收藏
- 关注
原创 智能指针的使用及其原理
下面程序中我们可以看到,new了以后,我们也delete了,但是因为抛异常导致后面的delete没有得到执行,所以就内存泄漏了,所以我们需要new以后捕获异常,捕获到异常后delete内存,再把异常抛出,但是因为new本身也可能抛异常,连续的两个new和下面的Divide都可能会抛异常,让我们处理起来很麻烦。智能指针放到这样的场景里面就让问题简单多了。
2025-07-28 16:23:42
548
原创 C++11语法
C++11是C++的第二个主要版本,并且是从C++98起的最重要更新。它引入了大量更改,标准化了既有实践,并改进了C++程序员可用的抽象。在它最终由ISO在2011年8月12日采纳前,人们曾使用名称C++0x,因为它曾被期待在2010年之前发布。C++03与C++11期间花了8年时间,故而这是迄今为止最长的版本间隔。从那时起,C++有规律地每3年更新一次。
2025-07-26 15:45:46
843
原创 哈希表实现
哈希(hash)又称散列,是一种组织数据的方式。从译名来看,有散乱排序的意思。本质就是通过哈希函数把关键字key跟存储位置建立一个映射关系,查找时通过这个哈希函数计算出key存储的位置,进行快速查找。
2025-07-23 15:28:24
649
原创 红黑树实现
红黑树是一颗二叉搜索树,他的每个结点增加一个存储位来表示结点的颜色,可以是红色或者黑色。通过对任何一条从根到叶子的路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出2倍,因而是接近平衡的。
2025-07-20 14:25:00
1102
原创 AVL树实现
通过本图可以看到,左边高时,a子树高度从h变成h + 1,引发旋转,可是右单旋无法解决问题,右单旋后,我们的树依旧不平衡。右单旋解决的是纯粹的左边高,但是10为根的子树不再是单纯的左边高,对于10是左边高,但是对于5是右边高,所以需要用两次旋转才能解决,以5为旋转点进行一个左单旋,再以10为旋转点进行一个右单旋,这棵树就平衡了。跟左右双旋类似,要对15为旋转点进行一次右单旋,再对10为旋转点进行一次左单旋。旋转总共分四种,左单旋/右单旋/左右双旋/右左双旋。也需要分三种情况去分析。
2025-07-18 16:25:46
1040
原创 map和set的使用
1. set的声明如下,T就是set底层关键字的类型。2. set默认要求T支持小于比较,如果不支持或者像按照自己的需求走的可以自行实现仿函数给传给第二个模板参数。3. set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个模板参数。4. 一般情况下,我们都不需要传后两个模板参数。5. set的底层是红黑树实现,增删查效率是O(logN),迭代器的遍历走的是搜索树的中序遍历,所以是有序的。
2025-06-14 17:37:56
817
原创 C++多态讲解
多态是一个继承关系的下的类和对象,去调用同一个函数,产生了不同的行为。比如Student继承了Person。Person对象买票是全价,Student对象买票优惠。
2025-05-12 23:17:53
1065
原创 二叉搜索树讲解
二叉搜索树又称二叉排序树,它或者是一颗空树,或者是具有以下性质的二叉树:1. 若它的左子树不为空,则左子树上的所有结点的值都小于等于根节点的值。2. 若它的右子树不为空,则右子树上的所有结点的值都大于等于根节点的值。3. 它的左右子树也分别为二叉搜索树。4. 二叉搜索树中可以支持插入相等的值,也可以不支持插入相等的值,具体看使用场景定义。
2025-05-11 22:00:57
890
原创 C++继承语法讲解
下面我们看到Person是基类,也称作父类。Student和Teacher是派生类,也成为子类。(因为翻译的原因,所以也叫基类/派生类,也叫父类/子类)。
2025-05-08 20:09:36
1066
原创 C++模板
class 类模板名1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此产生。2. 增强了代码的灵活性。1. 模板会导致代码膨胀问题,也会导致编译时间变长。2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。
2025-05-07 21:54:34
1122
原创 stack,queue和priority_queue
队列也是一种容器适配器,专门设计用于在FIFO(先进先出)中操作,其中元素插入容器的一端并从另一端提取。优先级队列也是一种容器适配器,它是由堆这种数据结构封装的,是严格按照顺序来存放数据的。默认是大堆,可以用 greater 类去改变成小堆。
2025-04-19 22:23:44
388
原创 list容器
尾插一个元素。尾删一个元素。在指定迭代器的前一个元素后面插入元素。4. size()计算元素大小。5. front()返回第一个元素。6. back()返回最后一个元素。删除迭代器位置元素。
2025-04-12 22:49:59
441
原创 vector
vector - C++ Reference1. vector();无参构造。2. vector(size_t n, const T& value);用n个value去构造一个vector。3. vector(const vector<T>& v);拷贝构造,用另一个vector去构造一个vector。4. vector(InputIterator first, InputIterator last);用迭代器区间去构造一个vector。2. 迭代器1. begin() + end()获取第一个数
2025-03-02 16:22:51
494
原创 string
大家可以去这个网站去访问,非常的方便。在使用string类时,必须包含#include<string>头文件以及using namespace std;
2025-01-26 20:29:40
974
原创 类与对象——下
1. 之前我们实现构造函数时,初始化成员变量主要是使用函数体内赋值,构造函数初始化还有一种方式,就是初始化列表,初始化列表的使用方式是以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个”成员变量“后面跟着一个放在括号中的初始值或表达式。2. 每个成员变量在初始化列表中只能出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。3. 引用成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否则会编译报错。
2025-01-12 15:52:24
1058
原创 类和对象——中
默认成员函数就是用户没有显示实现,编译器会自动生成的成员函数称为默认成员函数。一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,稍微了解以下即可。默认成员函数很重要,也比较复杂,我们要从两个方面去学习:1. 我们不写时,编译器默认生成的函数行为是什么?是否满足我们的需求。2. 编译器默认生成的函数不满足我们的需求,我们需要自己实现,那么如何自己实现?
2025-01-08 18:28:01
1036
原创 类和对象——上
1. class为定义类的关键字,Date为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。2. 为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面加_或者m开头,注意C++中这个并不是强制的,只是一些惯例。
2024-12-13 14:12:47
966
原创 C++入门基础
1. 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。2. namespace本质是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不在冲突了。3. C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。
2024-12-09 17:51:18
1370
原创 题目讲解20 链表中倒数最后k个结点
第三步:开始找最后k个结点,要分两种情况来去找。如果k是大于链表数据个数的话直接返回NULL,还有一种就是正常情况,我们写个函数。要找到倒数第k个结点,也就是要找到它的前驱结点,由于是单链表,所以我们只能从头结点开始一个一个的去遍历,我们需要遍历n - k次,(n就是链表数据个数)。第一步:写一个计算链表数据个数的方法。第二步:定义一个结构体指针用来返回。
2024-11-24 15:35:54
259
原创 题目讲解19 链表中环的入口结点
第二步:遍历整个链表,用快慢指针去看链表有没有环,如果快慢指针相遇了说明链表带环。但是这个时候我们还不知道环的入口结点是哪个,我们需要再定义一个结构体指针pcur指向头结点,从头结点开始遍历,pcur走一步,slow也跟着走一步,等到pcur和slow相遇时,pcur所指向的结点就是环的入口结点。需要用到快慢指针算法,快慢指针算法也就是慢指针一次走一步,快指针一次走两步。已经找到了入口结点,直接返回。也有可能链表不带环,直接返回NULL。第一步:创建两个结构体指针slow和fast,都指向链表头结点。
2024-11-21 15:13:26
284
1
原创 题目讲解18 有效的括号
第三步:通过字符指针开始遍历数组,如果是左括号就把数据入栈,不是的话就要取栈顶数据来和*pi的值对比,如果不匹配就可以直接返回false了。如果遍历完了都没有返回false的话,还不能直接返回true,因为栈中可能还有左括号,所以还需要最后判断一下栈是否为空,为空了才是true,不为空就是false。第二步:定义一个栈结构变量并初始化,再定义一个字符指针指向字符串。第一步:先搭建一个数据结构——栈。
2024-11-19 14:44:50
309
原创 题目讲解17 判断链表中是否有环
第二步:遍历链表,慢指针一次走一步,快指针一次走两步,如果链表有环的话,两个指针是一定会相遇的。这就像在操场上跑步一样,跑的快的肯定会再次看见跑的比他慢的。fast遇到了slow就说明有环,如果遍历完了链表还没有相遇,那就是链表无环。第一步:创建两个指针,让它们都指向链表的头结点。这题需要用到快慢指针算法。
2024-11-17 17:33:02
208
原创 题目讲解16 删除链表的倒数第 N 个结点
2. 如果要删除的结点是头结点但n!= 1时,先保存头结点的下一个结点,删除头结点,然后在让头结点指向之前保存的结点。1. 如果链表只有1个元素并且n = 1时,要删除的就是那个元素,所以直接返回NULL。3. 正常情况,就可以直接调用写的删除结点方法了。第一步:写两个链表方法。第二步:分三个情况考虑。2. 计算链表结点个数。
2024-11-15 14:46:12
282
原创 题目讲解15 合并两个排序的链表
第三步:进行遍历判断。如果 l1 结点里的值小于 l2 结点里的值,就把 l1 结点里的值尾插到返回链表。反之,就把 l2 结点里是值尾插到返回链表。如果 l1 或者 l2 遍历到 NULL 的时候,会有一方没有完全遍历完所有结点,所以我们还需要补上两个循环去遍历完 l1 或者 l2。第二步:创建三个链表结点。l1 用来遍历链表1,l2用来遍历链表2,RetList 是返回链表。第一步:写一个链表尾插数据的方法。
2024-11-10 16:22:10
724
原创 题目讲解14 链表内指定区间反转
第五步:依次把反转完的数组依次尾插到返回链表中,然后返回链表即可。第一步:先写出一些我们需要用到的单链表操作。第二步: 定义一个数组和一个用来返回的链表。第三步:把原链表里面的元素依次存放到数组里。
2024-11-04 21:07:14
278
原创 题目讲解13 反转链表
第二步:把n2 的 next 指针指向 n1,然后n1 指向 n2,n2 指向 n3,n3 在指向它的下一个结点,依次循环。第一步:建立三个指针,n1 指向空,n2 指向头结点,n3 指向头结点的下一个结点。光看这个代码可能难以理解,我给大家画几个图。第三步:返回n1 即可。
2024-11-03 15:45:36
277
原创 题目讲解12 日期问题
第三步:再去把合法的日期,在一一的和题目的判断条件去对比,符合的输出即可。第二步:再去判断分割出来的年月日是否合法。第一步:枚举所有的日期,分割年月日。
2024-11-02 16:34:10
256
原创 题目讲解11 两数相加
第四步:把结果数组里面的数据依次尾插到返回链表里面,但是这里要分两种情况去判断,如果max 下标的值不是零的话,说明进位了,所以要把进位了的数也要尾插进去。第三步:把两个数组依次相加,然后把结果放在结果数组里面。第二步:创建两个数组分别依次存入两个链表里的数据。第一步:先创建一个单链表。
2024-11-01 16:46:59
180
原创 C语言编译和链接
在 ANSI C 的任何一种实现中,存在两种不同的环境。第一种是翻译环境,在这个环境中源代码被转换成为可执行的机器指令(二进制)。第二种是运行环境,它用于实际运行代码。
2024-09-29 17:08:51
1185
原创 文件的讲解
char c = 0;c <= 'z';pf = NULL;return 0;我们拿 abcdef 来举例。如果你想要 读到 a 和 d 的话,有三种方法。
2024-09-29 11:00:22
2098
原创 结构体讲解
结构体是一些值的集合,这些值称为成员变量,结构体的每个成员可以是不同类型的变量。结构体还有一种特殊的声明,也就是匿名结构体。2它的特点是省略掉了结构体类型名 tag。要注意的是,
2024-09-16 14:43:15
406
原创 整数和浮点数在内存如何存储
我们都知道计算机里面的所有数据都是用二进制来存储的,整数的二进制有三种表示的方式,分别是原码,反码和补码。原码,反码和补码一般都是32个比特位,第一位是符号位。其中有符号整数的符号位为 0,无符号整数的符号位 1.正数的原码,反码和补码是相同的,负整数的三种表示方法各不相同。原码:直接将整数按照正负数的形式转换为二进制得到的就是原码。反码:将原码的符号位不变,其他位取反,取反也就是把 0 变为 1,1 变为 0。补码:将反码 + 1就是补码。
2024-09-14 13:18:59
323
原创 题目讲解10 绝对值排序
第二步:写一个数字交换的函数,因为不仅要排序原数据,也要排序绝对值数据,所以封装成函数比较方便。循环遍历,进行排序。第一步:建立两个数组,一个用于存放原数据,一个用于存放绝对值。第三步:循环输出原数据即可。
2024-09-08 17:16:03
323
原创 题目讲解9 水仙花数判断
第二步:写一个判断水仙花数的函数。水仙花数的特征就是个位数的立方和 + 十位数的立方和 + 百位数的立方和 = 它自己本身。% 10 就可以取下一个数的最后一位,然后在 / 10,就可以继续取下一位,再把取下的数的立方和全都加起来再返回。第三步:循环遍历所有的三位数,然后把符合条件的数据输出即可。第一步:建立一个用于循环的变量 i。
2024-09-05 13:54:27
473
原创 题目讲解8 日期换算
第一步:建立两个变量 month 和 day 去接受数据,再建立一个数组去存放2019年每个月的天数。第二步:计算除了本月的之外前面所有月份的天数。第三步:输出算出的和加上本月的天数即可。
2024-09-04 12:46:31
429
原创 题目讲解7 字符串移位包含问题
每移位一次就进行判断,看看 a 数组是否包含数组 b 了,如果包含了就输出 true ,再程序返回。如果全部移位完了还没有输出 true ,就可以输出 false 了。第二步:先进行一次判断,看看 a 数组里面是否包含 数组 b。如果不包含就在继续进行下一步,包含的话就直接输出 true 然后程序返回。已经不能在移位了,因为在移就和初始字符串重复了,所以结论就是一个字符串只能移位它的长度减一次。第三步:开始循环移位,循环移位的条件就是 数组 a 长度减一,就用题目给的例子示范一遍。ABCDA 移位一次。
2024-09-01 11:22:08
312
原创 题目讲解6 输出亲朋字符串
第一步:建立字符数组 arr,用于存放数据。因为它说数据不大于63,也就是意味着里面会有空格,那就不能用 scanf 函数了,需要用到 gets 函数。第二步:循环遍历数组,如果是最后一个字符就输出该字符和第一个字符的和,不是的话就输出该字符和下一个字符的值。scanf 和 gets 的区别就是 scanf 是到空格就停止输入,gets 是可以把空格也输入进去。
2024-08-30 17:04:46
306
原创 题目讲解4 查找最大元素
第三步:循环遍历,如果是最大的字符就输出该字符和字符串(max),不是的话就只输出该字符即可。第一步:建立两个字符数组,一个放输入的数据,一个放字符串 (max)。第二步:找最大的元素。
2024-08-28 18:55:19
333
原创 题目讲解3 蓝桥杯算法训练VIP-反置数
第一步:把这两个的数反置,然后在把反置之后的数加起来。反置这个过程会多次使用,可以封装成一个函数。n % 10 求的数就是 n 的个位数。第二部:把这个和在反置,然后输出即可。
2024-08-27 19:08:23
305
3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅