C/C++
文章平均质量分 67
知识总结
halooy
这个作者很懒,什么都没留下…
展开
-
数据结构-常见排序算法概念及实现
插入排序:①直接插入排序②希尔排序选择排序:①选择排序②堆排序交换排序:①冒泡排序②快速排序归并排序:归并排序原创 2023-09-05 16:31:30 · 66 阅读 · 0 评论 -
对B-树的理解
搜索二叉树,极端场景下会退化,类似于单支,此时的效率变成了O(N);为了解决1的问题,提出了平衡树的概念,左右子树的高度差不大于1,AVL树,红黑树。该效率为O(logN),其中map/set就是由此构建的;更好的搜索结构则有哈希/散列表,该效率为O(1),–unordered_map/unordered_set跳表、字典树上面的结构都是完成内存中数据的搜索查找问题但假设此时的数据量很多,在内存中存放不下,数据要存到磁盘中,上面的数据结构就不好了,虽然可以。原创 2024-07-13 16:31:44 · 996 阅读 · 0 评论 -
C++中的四种强制类型转换操作符
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)reinterpret_cast操作符通常为操作数的位模式提供较低层次的。都可用static_cast,但它不能用于两个不相关的类型进行转换。static_cast用于非多态类型的转换(静态转换),编译器。,用于将一种类型转换为另一种不同的类型。const_cast最常用的用途就是。dynamic_cast用于。原创 2023-11-11 17:39:12 · 202 阅读 · 0 评论 -
智能指针的理解
之前定义指针申请内存空间使用后要进行delete进行资源释放,但是如果在资源释放之前就抛出异常,则不会进行正常的资源释放,造成资源泄露的问题。长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。// 1.内存申请throw;因此通过定义智能指针,利用对象的生命周期来控制程序资源,在生命周期结束时自动释放资源。原创 2023-11-10 12:58:09 · 139 阅读 · 0 评论 -
thread类--线程操作使用细则
函数名功能thread():构造一个线程对象,没有关联任何线程函数,即没有启动任何线程:构造一个线程对象,并关联线程函数fn,args1,args2,…为线程函数的参数get_id():获取线程idjionable():判断线程是否还在执行,joinable代表的是一个正在执行中的线程。jion():该函数调用后会阻塞住线程,当该线程结束后,主线程继续执行detach():在创建线程对象后马上调用,用于把被创建线程与线程对象分离开,分离的线程变为后台线程,创建的线程的"死活"就与主线程无关。原创 2023-11-08 09:02:26 · 106 阅读 · 0 评论 -
lambda表达式
lambda表达式书写格式:[capture-list] (parameters)mutable -> return-type { statement},如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了Lambda表达式。通过以上例子可以看出lambda表达式的使用对于代码的简化有很大帮助,以下详细讲解lambda表达式语法。也可以通过自定义泛型,该方法在调用sort()时需要将泛型填入参数列表。原创 2023-11-04 17:00:07 · 144 阅读 · 0 评论 -
unordered系列关联式容器--哈希结构详细讲解及使用示例
即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个。对元素的关键码进行同样的计算,把求得的函数值当做元素的存储位置,在结构中按此位置取元素比较,若关键码相等,则搜索成功。根据待插入元素的关键码,以此函数计算出该元素的存储位置并按此位置进行存放。中,元素关键码与其存储位置之间没有对应的关系,因此在。,搜索的效率取决于搜索过程中元素的比较次数。例如:数据集合{1,7,6,4,5,9};原创 2023-10-31 21:06:36 · 158 阅读 · 0 评论 -
红黑树--讲解以及详细实现过程
为了后续实现关联式容器简单,红黑树的实现中增加一个头结点,因为根节点必须为黑色,为了与根节点进行区分,将头结点给成黑色,并且让头结点的 pParent 域指向红黑树的根节点,pLeft域指向红黑树中最小的节点,_pRight域指向红黑树中最大的节点。,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。没有AVL树那么严格的要求必须左右子树高度差小于1。红黑树,是一种二叉搜索树,但。尚未结束~~持续更新。原创 2023-10-26 20:36:00 · 112 阅读 · 0 评论 -
二叉搜索树进阶--AVL树详细实现过程
之前学习到的虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将,查找元素相当于在顺序表中搜索元素,效率低下。,即可降低树的高度,从而减少平均搜索长度。原创 2023-10-23 23:27:24 · 176 阅读 · 0 评论 -
树形结构关联式容器--set、map、multiset、multimap介绍及使用
set是按照一定次序存储元素的容器在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。set在底层是用二叉搜索树(红黑树)实现的。注意。原创 2023-10-21 18:24:02 · 169 阅读 · 0 评论 -
二叉树的前序、中序、后序遍历 -- 非递归方式实现
3.判断top节点是否可以压入vector,条件为top节点的右子树为空,或者top节点的右子树已经被压入vector。1.首先用一个while循环将二叉树的最左路径节点全部压入栈内,同时由于前序遍历的特性,也。将该节点获取为当前节点后,对栈顶元素进行移除,前序遍历是在将二叉树最左路径节点压入栈的同时,也将该节点的值压入vector。4.重复循环,直到当前节点为空,或者栈为空。4.重复循环,直到当前节点为空,或者栈为空。4.重复循环,直到当前节点为空,或者栈为空。一个指向当前节点、一个指向上一栈顶节点。原创 2023-10-20 15:21:30 · 115 阅读 · 0 评论 -
二叉搜索树--详细实现过程
比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文就构成一种键值对;KV模型:每一个关键码key,都有与之对应的值Value,即的键值对。最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为:O(log_n)最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为:O(n)插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。原创 2023-10-19 18:53:38 · 116 阅读 · 0 评论 -
多态理解以及重载、重写和重定义的区别
两个函数在同一作用域函数名/参数相同两个函数分别在基类和派生类的作用域函数名相同两个基类和派生类的同名函数不构成重写就是重定义。原创 2023-10-14 18:19:06 · 72 阅读 · 0 评论 -
C++中文件流的简单读写操作、string流使用介绍
ofstream:输出文件流。ifstream:输入文件流。stringstream流。原创 2023-10-09 12:23:38 · 241 阅读 · 0 评论 -
vector、list、deque的优缺点
deque(双端队列):增容代价小1.数据缓冲区已满,新开一个缓冲区,缓冲区首地址存入指针数组2.指针数组已满,新开一个指针数组,只需要拷贝原有缓冲区的指针,不需要拷贝元素内容通俗解释:创建一个指针数组,从中间开始存储,比如chunk1 指向一个数据缓冲区用来存储数据,当进行头插尾插占满该缓冲区后,**再进行头插时,对指针数组进行–,chunk0指向一块新的数据缓冲区用来存储头插操作;再进行尾插时,对指针数组进行++,chunk2指向一块新的数据缓冲区用来存储尾插操作。原创 2023-10-08 22:22:25 · 269 阅读 · 0 评论 -
queue和priority_queue的介绍、使用以及实现
队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:empty:检测队列是否为空size:返回队列中有效元素的个数front:返回队头元素的引用back:返回队尾元素的引用。原创 2023-10-08 14:22:21 · 120 阅读 · 0 评论 -
stack的介绍、使用以及实现
当需要找出栈内元素最小值时,需要对栈进行遍历操作,时间复杂度为O(n)。3.在对栈内元素进行出栈操作时,需要将该元素和最小栈栈顶元素进行比较,如果相等,也同时将最小栈的栈顶元素进行出栈。push(入栈):push_front 头插(效率最高为O(1),尾插需要从头遍历一遍效率是O(n))push(入栈):push_back 尾插(效率最高为O(1),头插的话效率是O(n))2.第二个元素开始不同,将第二个元素和最小栈中的栈顶元素进行比较,pop() :将stack中尾部的元素弹出。原创 2023-10-07 13:22:06 · 148 阅读 · 0 评论 -
list模拟实现--代码详解
之前实现vector迭代器时定义的begin函数直接返回start指针(该指针直接指向数据本身)。但由于在实现list迭代器时,list的指针指向的是。因此在进行解引用时,不会得到数据本身,同时进行++操作时也不会得到下一个节点的位置。该list中析构函数的实现与先前stirng和vector不同在于需要循环释放每个节点的资源。由于list的底层是双向链表结构,因此在进行list模式实现时需要先定义一个。:指向先前定义的节点结构体类型的指针。:用来指向下一个节点的指针。:指向节点类型的指针。原创 2023-10-05 15:50:40 · 34 阅读 · 0 评论 -
list---list的介绍及使用
list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代;list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素;list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效;与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好;原创 2023-10-02 18:06:12 · 61 阅读 · 0 评论 -
vector的模拟实现--代码详解
通过指定参数的类型来存放处理不同类型的数据。:指向有效位置的最后一位(size的最后一位):指向有效位置的起始位置(size的第一位):指向空间最后一位(相当于capacity)string类能够存放处理的数据类型有限;这里则运用了之前写过的。原创 2023-09-27 12:15:03 · 59 阅读 · 0 评论 -
vector---vector介绍以及使用
vector是表示可变大小数组的序列容器。像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。原创 2023-09-26 15:06:07 · 100 阅读 · 0 评论 -
String类的模拟实现---String类的构造、拷贝构造、析构函数以及赋值运算符重载等
以下分别包括传统写法和现代写法:传统写法每一步都通过申请空间,资源清理、释放空间;现代写法理解为进行了偷懒,通过调用构造函数、拷贝构造来实现。原创 2023-09-24 14:04:23 · 77 阅读 · 0 评论 -
STL--string类--常用接口;string类对象的容量、访问及遍历、修改操作;非成员函数
在。原创 2023-09-23 17:15:08 · 61 阅读 · 0 评论 -
泛型编程的概念讲解以及如何实现
先理解一下例如:我们要实现一个交换函数,但是在使用过程中,可能需要对多个不同类型的参数进行交换。比如第一次需要交换两个整型变量,第二次需要交换两个字符变量,第三次需要交换浮点型…在C++里面我们可以通过来实现,函数重载可以通过传入的参数类型不同来进行调用相应的函数。和。原创 2023-09-22 15:43:30 · 51 阅读 · 0 评论 -
C++内存管理方式--通过new和delete操作符进行动态内存管理详细讲解
delete ptr;new: operator new --> malloc --> 构造delete:析构 --> operator delete --> freedelete pa;new[]:operator new[] --> operator new --> malloc --> N次构造delete[]:N次析构 --> operator delete[] --> operator delete --> free。原创 2023-09-22 14:10:28 · 100 阅读 · 0 评论 -
malloc、calloc、realloc、free理解
比如ptr4要在ptr3的基础上再往后申请100个字节空间,如果不够,则会重新找一块新的空间。realloc里面会帮助我们释放,不需要在外面再显式释放传入的ptr3空间:因为传入的ptr3空间可能被释放也可能没有被释放,主要看后面有没有可利用的空间,如果没有则会被释放,申请更大的空间。以上realloc申请的空间在释放空间时会有所不同,按理说开辟了三个空间后,应该释放三个空间大小,但是运行会报错,因为。调整空间大小,给原先只开辟一个字节空间大小的ptr,扩充到两个字节空间大小。先开辟一个字节的空间大小。原创 2023-09-21 22:45:28 · 41 阅读 · 0 评论 -
C++内存管理的理解--不同位置定义的变量分别存放在栈、堆、数据段还是代码段?以及大小、长度
- 栈:在函数内部定义的局部变量/函数参数/返回值等,存放在函数栈内。 - 堆:通过动态开辟出来的空间,都放在堆上,比如定义了一个指针指向一块动态开辟的空间,指针本身可能存放在别的地方,但是该指针存放的内容是堆上的地址,**该指针的解引用获取的内容也是堆上的东西**。 - 数据段:**包含全局数据和静态数据**。全局定义的变量,或者任何位置(全局或者函数内部)定义的静态变量都存放在数据段中。 - 代码段:可执行代码/只读常量。文本数据等都属于常量,存放在代码段中。原创 2023-09-21 15:31:03 · 329 阅读 · 0 评论 -
类与对象---explicit、static关键字、友元介绍
初始化列表初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。原创 2023-09-20 23:01:52 · 45 阅读 · 0 评论 -
类与对象--常见成员函数
当程序退出时,s2和s1要进行销毁操作,s2先销毁,当s2销毁时调用析构函数,将s2所指空间释放,但s1不知道,到s1销毁时,会对同一空间再释放一次。析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。编译器自动生成的拷贝构造:完成对象内容的拷贝,或者称为字节序拷贝,这种情况称为浅拷贝(不会拷贝对象的资源)1.如果没有显式定义构造,则编码器自动生成无参构造,否则,编译器不在生成无参构造。因为此时拷贝过去的是指针,等于s1和s2指向同一地址,最后造成二次释放;原创 2023-09-18 22:57:12 · 56 阅读 · 0 评论 -
大小端概念及测试、结构体对齐规则
大端:低地址存高位,高地址存低位。小端:低地址存低位,高地址存高位。原创 2023-09-17 23:08:31 · 133 阅读 · 0 评论 -
类和对象详解
C语言时的,关注的是,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于的,关注的是,将一件事情拆分成不同的对象,靠对象之间的交互完成。原创 2023-09-15 11:28:43 · 30 阅读 · 0 评论 -
内联函数、auto、范围for概念讲解
的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。如果函数简单,会进行直接展开;如果函数过于复杂,还是会进行函数的正常调用。一行定义多个变量时,表达式推导出的类型必须一致。范围for: 当前数据:循环的范围。一般用于类型特别长时使用auto。auto不能直接用来声明数组。根据表达式来推导变量的类型。auto不能作为函数的参数。提高遍历效率,避免越界访问。定义指针:*可加可不加。原创 2023-09-14 19:57:36 · 58 阅读 · 1 评论 -
变量引用概念
引用:相当于起了一个外号,但还是代表它本身。引用与赋值的区别在于:引用与变量使用同一个空间地址。赋值则是从新开辟一个空间。原创 2023-09-14 14:30:03 · 106 阅读 · 1 评论 -
命名空间、函数重载理解
如果不想每次都加 std:: 也可以直接在最开始展开命名空间:using namespace std;C++实现可以通过对同一函数传入不同类型的参数(C语言中,同一作用域,函数名不能重复)在C语言中如果需要传入不同的参数,则需要调用定义不同的函数。在C++中,头文件中定义的所有成员都属于std命名空间。缺省参数:定义函数时,给参数一个默认值。函数重载:函数名相同,参数不同:参数。以下示例:函数名相同,参数不同:参数。:参数从右向左填写,中间不能有空值。:只有返回值类型不同,:所有参数都有默认值。原创 2023-09-13 15:04:44 · 69 阅读 · 1 评论 -
数据结构-二叉树链式结构的实现
所谓遍历即沿着某条搜索路线,依次对树中每个结点均做一次且做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一,是二叉树上进行其他运算之基础。:是根据访问节点操作发生未知明明。原创 2023-09-02 22:59:12 · 55 阅读 · 1 评论 -
数据结构-二叉树、堆的概念及结构
树是一种非线性的数据结构,由n(n>=0)个有限结点组成一个具有层次关系的集合,把它叫做树是因为它看起来像一颗倒挂的树,也就是说它是跟朝上,而叶朝下的。用链表来表示一颗二叉树,通常方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该节点左孩子和右孩子所在的链结点的存储地址。一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。原创 2023-09-01 17:50:59 · 74 阅读 · 1 评论 -
有效括号判断
给定一个只包括( ){ } [ ] 的字符串,判断字符串是否有效。定义一个二维数组,将左右字符串依次放入(映射关系)1.左括号必须用相同类型的右括号闭合。通过遍历字符串,左括号入栈,右括号匹配。注意空字符串可被认为是有效字符串。2.左括号必须以正确的顺序闭合。输入:”{ [ ) }“原创 2023-08-30 16:06:17 · 89 阅读 · 0 评论 -
数据结构-栈、队列篇
单链表, 尾插O(n), 头删O(1) 含有尾指针的单链表,尾插O(1),头删O(1)常用实现:顺序表 pushBack -->入栈 popBack --> 出栈。:尾插O(1) 头删O(n)常用实现:含有尾指针的单链表。原创 2023-08-30 14:02:02 · 30 阅读 · 0 评论 -
数据结构-带头双循环链表实现
结构最复杂,一般用在单独存放数据,实际中使用的链表数据结构,都是带头双循环链表。该结构虽然结构复杂,但是使用代码失陷后会发现带来很多优势,实现反而简单。原创 2023-08-23 14:12:13 · 34 阅读 · 0 评论 -
数据结构-带头单向非循环链表实现
【代码】数据结构-链表实现。原创 2023-08-23 13:58:46 · 50 阅读 · 0 评论