- 博客(27)
- 收藏
- 关注
原创 C++ 红黑树
c为红,p为红,g为黑,u存在且为红,则将p和u变黑,g变红。分析:因为p和u都是红色,g是黑色,把p和u变黑,左边子树路径各增加一个黑色结点,g再变红,相当于保持g所在子树的黑色结点的数量不变,同时解决了c和p连续红色结点的问题,需要继续往上更新是因为,g是红色,如果g的父亲还是红色,那么就还需要继续处理;c为红,p为红,g为黑,u不存在或者u存在且为黑,u不存在,则c一定是新增结点,u存在且为黑,则c一定不是新增,c之前是黑色的,是在c的子树中插入,符合情况1,变色将c从黑色变成红色,更新上来的。
2025-10-19 12:05:07
662
原创 C++ AVL树
跟左右双旋类似,下面我们将a/b/子树抽象为高度h的AVL子树进行分析,另外我们需要把b子树的细节进一步展开为12和左子树高度为h-1的e和f子树,因为我们要对b的父亲15为旋转点进行右单旋,右单旋需要动b树中的右子树。通过下图可以看到,左边高时,如果插入位置不是在a子树,而是插入在b子树,b子树高度从h变成h+1,引发旋转,右单旋无法解决问题,右单旋后,我们的树依旧不平衡。右单旋是用来解决的纯粹的左边高,但是插入在b子树中,10为跟的子树不再是单纯的左边高,对于10是左边高,但是对于5是右边高。
2025-10-16 10:47:15
1050
原创 C++ 前K个高频单词
解题思路:首先统计次数我们运用map的operator[]就可以很好的统计出单词出现的次数。接着我们进行对次数的排序,这里我们需要重载operator()来帮助我们实现对pair的比较大小。但在题目给出需要按字典顺序取出,我们如果只用sort会出现错误,因为sort是属于不稳定的排序,我们需要用到stable_sort即可完成题目。"the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,"i" 和 "love" 为出现次数最多的两个单词,均为2次。个出现次数最多的单词。
2025-09-19 15:34:34
287
原创 C++ map和set
set的声明如下图,T就是set底层关键字的类型set默认要求T支持小于比较,如果不支持或者想按自己的需求走可以自行实现仿函数传给第二个模版参数set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参数。一般情况下,我们都不需要传后两个模版参数。set底层是用红黑树实现,增删查效率是O(logN),迭代器遍历是走的搜索树的中序,所以是有序的。因为STL库实现的接口相似度高,我们就不一一展示,挑选重要的来理解学习。
2025-09-05 21:00:00
1031
原创 C++题目 环形链表II
解题思路:我们定义一个存放节点指针的set,然后我们通过指针去遍历链表,遍历一个节点如果不在set里面,我们就将访问的节点地址存放到set里面,接着遍历,如果发现某个节点地址已经存放在set里面,那么那个节点就是环的入口。指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数。如果链表中有某个节点,可以通过连续跟踪。,返回链表开始入环的第一个节点。来表示链表尾连接到链表中的位置(,仅仅是为了标识链表的实际情况。给定一个链表的头节点。如果链表无环,则返回。,则在该链表中没有环。
2025-09-05 16:56:53
224
原创 C++题目 两个数组的交集
接着我们通过用双指针,也就是两个迭代器去找交集,如果两个迭代器指向的值相等,那么就是交集,然后同时迭代器加加,如果不相等的话就小的加加(因为小的必然不是交集),其中一个set结束就程序结束。输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序。解题思路:首先我们将两组数据放入set里面,这样我们可以完成。解释:[4,9] 也是可通过的。
2025-09-02 11:20:23
205
原创 C++ 二叉搜索树
首先情况1把N结点的父亲对应孩子指针指向空,直接删除N结点(情况1可以当成2或者3处理,效果是一样的),情况2把N结点的父亲对应孩子指针指向N的右孩子,直接删除N结点,情况3把N结点的父亲对应孩子指针指向N的左孩子,直接删除N结点。那么这样的效率显然是无法满足我们需求的,我们后续学习二叉搜索树的变形,平衡二又搜索树AVL树和红黑树,才能适用于我们在内存中存储和搜索数据。2.要删除的结点N左孩子位空,右孩子结点不为空3.要删除的结点N右孩子位空,左孩子结点不为空4.要删除的结点N左右孩子结点均不为空。
2025-09-02 11:19:35
1068
原创 C++ 多态
从上面可以看出,C++对虚函数重写的要求比较严格,但是有些情况下由于疏忽,比如函数名写错参数写错等导致无法构成重写,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,因此C++11提供了override,可以帮助用户检测是否重写。的话,在我们自己生成了派生类的析构函数后析构p2会产生内存泄露,因为如果不是多态,delete调用析构函数会去调用基类的析构函数,而我们派生类里含有的资源就没有办法去清理,从而导致内存泄露。的下的类对象,去调用同一函数,产生了不同的行为。
2025-08-27 13:37:34
547
原创 C++ 继承
下面我们给出一个例子,可以看出Person是基类,也称作父类。Student是派生类,也称作子类。(因为翻译的原因,所以既叫基类/派生类,也叫父类/子类)。对于继承方式我们可以列出一些表格来对应不同的使用情况,但其实protected和private的继承方式十分少见。类成员/继承方式public继承protected继承private继承基类的public成员派生类的public成员派生类的protected成员派生类的private成员基类的protected成员。
2025-08-23 20:02:07
829
原创 C++ 模板提升
为什么会这样呢,是因为我们编译器在编译代码往往要进行四个步骤,分别是预处理(头文件展开/宏替换/条件编译/去掉注释...)编译(检查语法,生成汇编代码)汇编(汇编代码转换二进制机器码)链接(目标文件合并在一起生成可执行程序,并且把需要的函数地址等链接上)上述示例中,p1指向的d1显然小于p2指向的d2对象,但是Less内部并没有比较p1和p2指向的对象内容,而比较的是p1和p2指针的地址,这就无法达到预期而错误。使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果。
2025-08-19 14:50:55
855
原创 C++ priority_queue
priority_queue名叫优先级队列,它也是容器适配器。底层其实是堆。我们要使用它不需要包其他的头文件,只需要包含queue就可以使用。pop()和top()默认是大的优先级高,如果需要让小的优先级高的话,我们需要加入仿函数greater。接下来我们要来模拟实现priority_queue。
2025-08-17 21:39:57
248
原创 C++ stack_queue
虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque。
2025-08-15 16:17:08
905
原创 C++ list模拟实现
我们list的实现依旧先从源代码入手,我们需要搞清楚部分的逻辑,这样方便我们去模拟实现。link_type是节点的指针。接着我们去观察一下无参的初始化。这里弄得是哨兵位的节点。get_node是在内存池申请内存,类似malloc申请空间不初始化。接着我们来浅浅的观察一下push_back。某个位置前面插入。所以其实我们明白链表的结构,很多都能够大概猜测出来。
2025-08-13 20:44:59
879
原创 C++ vector模拟实现
为了更好的去了解vector底层,便于我们模拟实现,我们寻找适合自己的头文件源代码去阅读。我们能够发现vector的成员变量,然后我们大胆进行初步的猜测。当然不能仅仅通过猜测就能去确定,所以我们继续去研究核心接口大概怎么实现。这就是vector的构造函数我们找到push_back能够发现跟我们所想的差不多,end_of_storage是空间结束位置,finsh是数据结束位置,start就应该是开始位置了。再通过下面代码,我们就能够确定我们之前的猜测是没有问题的了。一、成员变量。
2025-08-01 16:36:17
752
原创 C++ 编码
ascii码值是老美用的,计算机进行全世界的推广就需要不同的编码表来表示不同国家的符号。内存和磁盘中只有0101,那是怎么能够表示符号的呢?这就衍生出编码的概念,编码是值和符号映射编码关系。因为我们自己汉字博大精深,又有字体,又有生僻字,还有不同民族的特殊语言,所以我们自己需要制作字库来使用。值一改变,字符也改变,这表现值与字符的映射。我们能够知道string为什么要写成模板,因为为了能够使用UTF-16或者UTF-32的编码。我们稍微改变一下,看看会发生什么变化。打印的时候其实是查找编码表的过程。
2025-07-26 10:09:01
334
原创 C++ string模拟实现
本文章的string模拟实现不考虑模板,不考虑那么多编码的问题,所以我们的头文件设定为源文件设定为。建立我们自己的命名空间,定义我们自己的string,为了简单化,我们string模拟实现的成员变量只定义_str和_size和_capacity。
2025-07-25 14:01:46
572
原创 C++ String
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。基本功能和find相似,只是rfind是在字符串中搜索由其参数指定的序列的最后一次出现,返回值是最后一个匹配项的第一个字符的位置,如果未找到匹配项,该函数将返回string::npos。我们在了解各个参数的含义可以结合网站的文章,再加上自己编程的经验。没有什么区别,都是字符长度。
2025-07-15 17:25:09
980
原创 C++ 类和对象(1)
2.对象大小 类实例化的对象,都有独立的数据空间,所以对象中肯定包含成员变量,但是成员函数并没有包含,因为当你如果使用成员函数一百遍的话,成员函数的指针要重复一百遍也太浪费了,所以其实函数指针是不需要存储的,函数指针是个地址,调用函数被编译成汇编指令[call 地址],其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址。 我们分析了对象中只存储成员变量,C++规定实例化的对象也要符合内存对齐的规则
2025-03-17 18:50:51
679
原创 C++入门基础 (1)
命名空间的定义需要用到namespace关键字,接着是命名空间的名字,接着用{}即可,在{}中可以定义有函数/变量/类型等。int n;命名空间本质上是定义了一个域,它与全局域是相互独立的,不同的域可以定义同名的函数变量等,用命名空间的话上面存在的命名冲突rand就可以解决。C++中域有函数局部域,全局域,命名空间域类域;域影响的是编译时语法查找一个变量/函数类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期。
2025-02-09 15:58:12
800
原创 C语言 扫雷游戏
但是例如9x9的扫雷中,我们选取周围的格子,外面的我们也要探索,所以我们干脆设定11x11的棋盘格子。我们要开始布置雷的位置,我们要随机或者坐标,来布置雷的位置,所以我们要用到随机数。因为我们要首先检查是否有雷,其次要在展示给玩家的棋盘中展示周围的情况。假设我们排查中间坐标的格子,那周围的格子的坐标我们都能求得,之后就统计周围的'1'的数量。因为如果没有中雷,我们要提供周围雷的数量,所以我们再在前面编写统计雷的个数的函数。当我们在输入我们检测的格子,肯定要弹出棋盘,所以我们要打印出棋盘给玩家观看。
2024-01-27 13:07:24
1163
1
原创 C语言分支与循环语句(基础)
如图我们就输出了1~10个数字运用了while循环语句。案例:输入一个正整数,计算这个整数是几位数?do while 平常我们使用的比较少。案例: 用C语言在屏幕打出10个hehe。例: 输入: 1234 输出 4。do while 基本格式如下图。for循环一般是我们在C语言中运用。for流程与while流程不大相同。do while 的流程图如下。这样我们就完成了这个案例。while循环的流程图(
2023-11-30 22:03:50
887
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅