- 博客(38)
- 收藏
- 关注
原创 c++11的一些新特性
关于C++11新特性,最先提到的肯定是类型推导,C++11引入了auto和decltype关键字,使用他们可以在编译期就推导出变量或者表达式的类型,方便开发者编码也简化了代码。
2024-01-12 20:32:02
1769
1
原创 avl树初步讲解
从新插入节点向上查找,第一个 a b s ( 平 衡 因 子 ) > 1 abs(平衡因子) > 1abs(平衡因子)>1的节点为根的子树,被称为最小不平衡子树。LR:新插入节点为最小不平衡子树根节点的左儿子的右子树上 → \rightarrow→ 以左儿子为根节点进行左旋,再按原始的根节点右旋。上图中,新插入节点向上查找,节点58左右子树高度差为2,以节点58为根节点的子树,就是最小不平衡子树。下图中,新插入节点18,使得以12为根节点的树成为不平衡二叉树,最小不平衡子树的根节点也是12。
2023-10-06 17:23:42
67
原创 红黑树的初步了解
对于二叉搜索树,如果插入的数据是随机的,那么它就是接近平衡的二叉树,平衡的二叉树,它的操作效率(查询,插入,删除)效率较高,时间复杂度是O(logN)。那么为了应对这种极端情况,红黑树就出现了,它是具备了某些特性的二叉搜索树,能解决非平衡树问题,红黑树是一种接近平衡的二叉树(说它是接近平衡因为它并没有像AVL树的平衡因子的概念,它只是靠着满足红黑节点的5条性质来维持一种接近平衡的结构,进而提升整体的性能,并没有严格的卡定某个平衡因子来维持绝对平衡)。红黑树是一种自平衡的二叉查找树,是一种高效的查找树。
2023-10-06 17:16:48
48
原创 位图和布隆过滤器
位图其实就是哈希的变形,他同样通过映射来处理数据,只不过位图本身并不存储数据,而是存储标记。通过一个比特位来标记这个数据是否存在,1代表存在,0代表不存在。位图通常情况下用在数据量庞大,且数据不重复的情景下判断某个数据是否存在。例如下面这道十分经典的题目给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。关于这道题目,解法其实有很多。1.快速排序后二分搜索。(内存可能不够,要16G内存)
2023-09-22 20:13:51
73
原创 linux中的gdb
在 Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件,Linux 系统所具备的这种功能又称为核心转储(core dump)。幸运的是,GDB 对 core 文件的分析和调试提供有非常强大的功能支持,当程序发生异常崩溃时,通过 GDB 调试产生的 core 文件,往往可以更快速的解决问题。down do 在当前调用的栈帧中选择要显示的栈帧。
2023-08-30 10:51:53
296
原创 map set c++
有别于set的是,map是一种key(键),value(值)的形式,用来保存键和值组成的集合,键必须是唯一的,但值可以不唯一。里面的元素可以根据键进行自动排序,由于map是key_value的形式,所以map里的所有元素都是pair类型。multiset允许key的冗余,如果用find查找key值时,找到的是中序遍历第一个,因此不断遍历下午可以找到这个multiset里所有的key值。map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。
2023-08-14 10:29:40
40
原创 二叉搜索树
恰巧这段代码又是尾递归的方式(尾递归就是程序分支的最后,也就是最后要返回的时候才出现递归),从编译的角度来讲,尾递归都可以用循环的方式去实现。当要删除的结点只有一个孩子结点,我们删除该结点后需要考虑怎么处置它的孩子结点。因为被删除的结点的孩子无论是左孩子还是右孩子,都只会比被删除的结点的父结点小,所以我们只需要将被删除的结点的父结点的指针指向被删除的结点的孩子结点。叶结点就是左右子树都为空的结点,既然左右子树都为空,删掉它并没什么后顾之忧,所以当我们要删除的是叶结点的时候,直接删除就好了。
2023-08-13 20:23:33
37
原创 虚函数与多态
一般继承(无虚函数覆盖)C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。关于虚函数的使用方法,我在这里不做过多的阐述。大家可以看看相关的C++的书籍。
2023-08-13 15:56:34
32
原创 c++继承
多继承是C++复杂的一个体现。有了多继承,就存在菱形继承,为了解决菱形继承,又出现了菱形虚拟继承,其底层实现又很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。
2023-08-12 14:56:04
49
原创 优先级队列
现在看优先级队列是不是就是“堆”了,如果最大的元素优先级最高,那么每次出队的就是当前队列中最大的元素,那么队列实际就相当于一个大顶堆,每次将堆根节点元素弹出,重新维护大顶堆,就可以实现一个优先级队列。此函数返回值为队列中优先级最高的元素,常与pop()函数一起,先通过top()获得队列中优先级最高的元素,然后将其从队列中删除;优先级队列的基本操作与普通队列类似,不同的是每次获得队内的元素是优先级最高的元素(要从堆的顶部开始),因此使用的是top()方法,而不是front()方法。队列空:返回true;
2023-08-11 21:28:53
134
原创 list的使用
通过此方式创建 values 容器,其中包含 10 个元素,每个元素的值都为相应类型的默认值(int类型的默认值为 0)。和空 array 容器不同,空的 list 容器在创建之后仍可以添加元素,因此创建 list 容器的方式很常用。5) 通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,可以创建新的 list 容器。4) 在已有 list 容器的情况下,通过拷贝该容器可以创建新的 list 容器。3) 创建一个包含 n 个元素的 list 容器,并为每个元素指定初始值。
2023-08-11 14:50:56
30
原创 vector的操作
end 成员返回容器最后一个元素的下一个位置(one past the end),也就是指向一个根本不存在的尾后位置,这样的迭代器没什么实际含义,仅是个标记而已,表示已经处理完了容器中的所有元素。为了避免每次改变 vector 时重新分配内存空间再将原来的数据从新拷贝到新空间的操作,标准库实现者采用了减少容器空间重新分配次数的策略:当不得不获取新空间时,vector(string 也是如此)通常会分配比需求更大的空间作为预留的备用空间,这样就减少了重新分配空间的次数。删除尾元素,返回void。
2023-08-11 14:13:38
47
原创 c++中string类的使用
find() 函数最终返回的是子字符串第一次出现在字符串中的起始下标。来拼接字符串时,运算符的两边可以都是 string 字符串,也可以是一个 string 字符串和一个C风格的字符串,还可以是一个 string 字符串和一个字符数组,或者是一个 string 字符串和一个单独的字符。第一个参数为待查找的子字符串,它可以是 string 字符串,也可以是C风格的字符串。string 变量也可以用C风格的字符串进行赋值,例如,s2 是用一个字符串常量进行初始化的,而 s3 则是通过 s2 变量进行初始化的。
2023-07-19 12:01:33
44
原创 c++之new和delete
指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放。的共同点是:都是从堆上申请空间,并且需要用户手动释放。掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。内存没有被释放,那么以后这部分空间将无法再被使用,就会产生。在空间上执行析构函数,完成对象中资源的清理工作。在申请的空间上执行构造函数,完成对象的构造。只会开辟空间,不会调用构造函数与析构函数,而。在申请空间后会调用构造函数完成对象的初始化,申请空间时,需要手动计算空间大小并传递,只需在其后跟上空间的类型即可,
2023-05-16 19:54:42
69
原创 c++之友元和内部类,以及类的匿名对象
内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。也就是说函数声明写在类里面,定义写在类外面。,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。但又会导致类外没办法访问成员,此时就需要友元来解决。友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。,不属于任何类,但需要在类的内部声明,声明时需要加。外部类,和内部类没有任何关系。
2023-05-13 15:49:35
45
原创 c++的初始化列表
静态成员函数的意义, 不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封 装。静态成员函数只能访问静态变量,不能访问普通成员变量 静态成员函数的使用和 静态成员变量一样 静态成员函数也有访问权限 普通成员函数可访问静态成员变量、也可以访问非静态成员变量。在一个类中,若将一个成员变量声明为 static,这种成员称为静态成员变量。静态成员变量必须在类中声明,在类外定义。概述:C++类中的静态成员一共有两种,静态成员变量和静态成员函数,被关键字 static 声明为静态的,称为静态成员。
2023-05-09 21:57:51
41
原创 cin和cout的进阶讲解
当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键(\r)会被转换为一个换行符\n,这个换行符\n也会被存储在cin的缓冲区中并且被当成一个字符来计算!说一下这里的const,首先ostream和istream之前不能加const,因为底层代码运作的时候istream会改变里面的东西,如果加了const就不能插入值了,ostream也需要先插入,同理不能加const。当然还有最简便的写法,但是这种就不符合我们平常的使用习惯,看看即可。
2023-05-06 13:30:29
169
原创 赋值运算符重载
上面的一般不用,下面是一般用的,是经典的赋值运算符重载。说明一下,这里的*this就是调用的主体本身。比如d1.operator(d2),那么*this和d1是一样的。当然,我们可以在运算符重载函数里面相互调用别的运算符重载函数,看个例子。型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。用于内置类型的运算符,其含义不能改变,例如:内置的整型。作为类成员函数重载时,其形参看起来比操作数数目少。然后区分一下两个东西,类Date还是用的上面这个。,因为成员函数的第一个参数为隐藏的。
2023-04-29 19:04:43
35
原创 c++专属成员函数之拷贝构造函数
这边st2调用拷贝构造函数会连开辟空间的地址都一模一样,也就是_a的值一样,到时候结束的时候调用析构函数,会连续两次清理同样的空间,那么就会报错,这也叫浅拷贝。我们执行Date d2(d1)时,如果拷贝构造函数是Date(const Date d)没有引用&,那么我们会无穷重复刚才的过程,不断调用拷贝构造函数,编译器不允许这样做,会直接报错,因此一定要有引用。答案是不行的,我们来看下面这个例子。当然,拷贝构造函数也可以改成下面这样,是一样的。拷贝,这种拷贝叫做浅拷贝,或者值拷贝。,因为会引发无穷递归调用。
2023-04-26 13:18:44
55
原创 c++专属成员函数之构造函数与析构函数
好,我们回过头看最上面这段代码,在之前我们需要调用Init()函数来初始化一个栈,而现在构造函数可以自动帮我们构造好。6. 关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下,编译器会生成默认的构造函数。析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。等自己定义的类型,看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员_t。是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务。
2023-04-22 21:58:49
73
原创 类和对象的入门之this初级知识
但是不能写出来的让它显性出现的,不然会报错。显然它是一个形参,那么和一般的形参一样,this指针存在函数调用的栈帧里面。上图说明空指针传参给this是可以的。这个函数的地址不在对象中,p会作为实参传给this指针。然后是下面这段代码。其实这两段代码除了cout
2023-04-22 19:23:02
32
原创 类和对象的入门
在一般代码中有三个域,优先级从小到大是局部域,类域,全局域。因此下面这段代码中并没有用到private中的x,只使用到了局部域,也就是使用函数传参的x。封装:将数据和操作数据的方式进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。注意类里面定义的函数默认是内联函数inline,函数太复杂就不会被认为是内联,这部分上次的博客有讲。同时,类也可以将声明和定义分离,看个例子,这种方法在实际使用中也会经常用到。c++中有三大特性,封装,继承和多态,而类和对象重点研究的就是封装。
2023-04-21 15:19:58
24
原创 内联函数和nullptr
/缺点:相当于把内联函数在使用到的位置展开(实际中有很多指令过程,这里简单的看成展开),如果函数特别大,那么最后在多个地方展开这个代码内存会爆炸。// inline对于编译器仅仅只是一个建议,最终是否成为inline,编译器自己决定(通常是10行以内的简单函数),如果函数特别复杂,通常编译器不会把它认为是内联函数。//内联函数声明和定义不能分离,不能出现下面这个情况:有声明在.h头文件里,定义在另一个源文件里。//优点:不需要建立栈帧,提高调用效率,简单,不容易出错、可读性好、可以调试。
2023-04-20 22:33:07
28
原创 深入c++中引用的使用
这里创造出一个x的int型临时变量,而临时变量具有常性,本身就是相当于有个const的属性,如果这里引用不加const修饰就是权限扩大,这是不被允许的,函数返回的时候也是一样,如果是返回值的话先创建一个临时变量再返回,如果是返回引用,比如返回n的引用,那么先创建临时变量int&a=n,再用int&ret=a接收。这里函数返回的是n的引用,ret是n的引用的引用,类似于下面这图。还有更好的写法,把改变结构体变量的函数放在结构体里面,再加个迭代器,当然这是c++的类独有的效果,c的结构体是没有的。
2023-04-19 16:11:15
28
原创 上次缺省的补充以及重载
如果有个头文件声明了一个函数(只写了有这个函数,没有具体去写出函数的具体内容),然后让另一个源文件去补充说明它的内容。重载函数:函数名必须相同,参数必须有不同(类型,个数,顺序),返回值可以相同,下面举例子。因此,缺省可以用在声明(类似头文件)中,但是不能用在定义(其他源文件)中!注意给一个变量引用之后不能改变引用对象,不然会报错,如下。那么运行结果是1+2=3。再看一下下面这个情况。
2023-04-18 09:23:03
32
原创 c++入门
std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的,所以我们要使用标准库中的函数或者对象都要用std来限定。同时,释放之后使用一些东西,我们要避免变量名与库函数或者库中变量名相同,不然编译器会报错。当然,如果我们需要域不被释放,同时发现类似全部cout前都没加域限定,那么我们可以释放一部分。可以看到是从左往右给参数的传值的,那么看一下下面情况,也可以验证这句话。namespace也可以合并,比如下面,输出0和1。域中可以有各种各样的东西,包括函数,结构体,域等等。
2023-04-17 20:44:59
25
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人