cpp
文章平均质量分 66
cleveryuoyuo
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
哈希hash
查找函数在线性探测的过程中进入循环是该位置不为空,循环内部判断当前位置值是否为所需要查找的值时,需要先判断该位置的状态为存在,再进行值得比较才可以。对于字符型数据,如果只取首字符很明显重复率很高,取单词的所有字符值的和也会很高(因为有aabb abab bbaa这样的数据会导致他们的和相同),因此有一个方法如下:对每个字符乘131然后再相加。2.如果存一个11,但是位置被占了,11存到了下标5的位置,但是我先把33删了,那个从11开始查,查到3的位置为空了,就停止了。相当于数组元素为一个一个的指针。原创 2025-01-13 11:02:55 · 942 阅读 · 0 评论 -
封装map、set
map和set的实现原创 2024-11-15 20:05:21 · 213 阅读 · 0 评论 -
红黑树分析
红黑树原创 2024-11-13 20:49:59 · 458 阅读 · 0 评论 -
map和set的基本使用
如果 x 不存在,则先调用插入make_pair(x,V()),插入成功或者失败都会返回个 pair< iterator, bool>,iterator 指向 x 的迭代器,bool 为判断 x 是否是新插入的,然后拿出pair 的 iterator 为指向 x 的 iterator it,然后it->second 为返回的value。如果找的 key 存在,插入失败,返回一个pair< 存在的key的节点迭代器,false >。set::lower_bound(x):找的是 >= x 的值。原创 2024-11-07 15:53:01 · 473 阅读 · 0 评论 -
二叉搜索树
左右都不是空 替换法删除 找到cur左子树最大的或者cur右子树最小的和cur的数值进行替换,替换完后把cur左子树最大的或者cur右子树最小的节点删掉。如果删除的节点cur右为null,则让cur的parent指向cur的左,下图是左为空的处理情况。如果删除的节点cur左为null,则让cur的parent指向cur的右。若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。平衡二叉树可以解决上述最差情况。它的左右子树也分别为二叉搜索树。原创 2024-11-06 19:34:11 · 545 阅读 · 0 评论 -
AVL树的旋转
AVL树原创 2024-11-08 20:10:47 · 1051 阅读 · 0 评论 -
多态的内容
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。多态必须在继承的条件下产生。多态的条件:1.父类完成虚函数重写(一般子类也写虚函数看着更清楚),虚函数需要完成函数名、参数类型、返回值相同。2.父类的指针或者引用去调用虚函数。在继承里,同名函数被隐藏,要想调用方的话得指定是在父类中的函数才能调用,而多态就解决了这个问题。多态的调用:运行时,到指向对象的虚表中找虚函数调用,指向父类调用父类虚函数,指向子类调用子类虚函数。普通调用:编译时,调用对象是原创 2024-11-05 19:25:29 · 977 阅读 · 0 评论 -
继承的内容
基类的private成员派生类怎样继承都是不可见(不能被直接访问)成员,但如果父类有public函数可以调用父类私有成员的话,可以在派生类中调用父类中的public成员去访问父类私有成员。继承的写法如下述代码所示:再代码中,基类的name和age都是portected,因此都是受保护的可以继承,继承后不能修改,但如果是基类的私有成员,继承后派生类中不可见。也就是说,对于很多都会共有的信息放在一个大类中,然后对于各个对象而言,想创建自己的信息类,可以继承一下大类,再添加一些自己特有的信息就行了。原创 2024-11-04 20:13:43 · 1016 阅读 · 0 评论 -
容器适配器、仿函数、优先级队列、deque、stack和queue题目
pop时,得先判定是否应该popstmin,如果先st.pop,则会导致判定的st的值已经被pop了。deque 头插尾插效率很好,但中间插入比较麻烦需要整体挪动,局部挪动,效率一般。vector:优点:支持下表随机访问,缺点:头部或者中间删除效率低+扩容有小号。栈和队列的默认容器是 deque,而栈和队列只需要头尾插入。list:优点:任意位置插入删除效率不错,缺点:不支持[]下标访问。队列经常用来广度优先遍历,也就是二叉树的层序遍历。deque:双端队列,但其实不是队列。上述图片是适配器实现的栈。原创 2024-10-29 15:46:04 · 301 阅读 · 0 评论 -
list 的实现
顺序表可以用原生指针代替迭代器的指针,但链表不可以,链表的指针++并不能够保证找到下一个节点的位置。下述代码为list的迭代器代码,对于拷贝构造使用浅拷贝就可以,因为只需要让另一个指针指向当前节点的资源,而链表不可以浅拷贝。const迭代器是迭代器指向的内容不能修改而不是迭代器本身不能修改,而const iterator是iterator不能修改,因此不满足需求。对于下述代码自定义类型A而言,如果想用迭代器->读取A的内容,就需要在迭代器中重载->,也就是定义的模板 Ptr 函数。原创 2024-10-26 15:34:10 · 564 阅读 · 0 评论 -
手写vector
【代码】手写vector。原创 2024-10-21 15:49:45 · 121 阅读 · 0 评论 -
STL-vector+题目
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。迭代器是容器通用的访问方式,使用方法基本相似。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。vector在[ ]和迭代器、范围for方面的使用差不多一样。vector的迭代器有普通的还有const类型的迭代器。输入:nums = [4,1,2,1,2] 输出:4。输入:nums = [2,2,1] 输出:1。输入:nums = [1] 输出:1。原创 2024-10-20 20:13:44 · 238 阅读 · 0 评论 -
list使用
splice:splice可以在自己的链表上操作,也可以把别的链表的部分转移到这个链表上。splice = transfers 转移 把一个链表中某些节点转移到别的位置去。转移是把链表的某些部分转移到让它去的位置的后面。如果把 lt1 转移到 lt2 上面,则 lt1 就没有节点了。list insert 不会失效, erase 会失效。insert 是在pos位置前面插入,pos是一个迭代器位置。vector insert/erase 会失效。clear 不会清除哨兵位节点。原创 2024-10-25 19:34:45 · 526 阅读 · 0 评论 -
链表题目解析
链表题目原创 2024-09-09 12:37:39 · 392 阅读 · 0 评论 -
链表的结构及单向不带头不循环链表
单项不带头不循环(对于下述代码的pplist参数,均需要在创建节点后,对结点指针再传递指针,也就是需要传递二级指针(&plist)进行使用。双向链表:具有数据域和指针域,分别有指针域指向下一个节点和上一个节点的地址。单链表的结构:具有数据域和指针域,指针域指向下一个节点的地址。phead:头指针 存放链表的第一个节点的地址。单链表带头节点的结构,头节点不存放有效数据。循环链表:最后一个节点指向头节点。但其实数据的存储不连续。1.无头单向非循环链表,2.带头双向循环链表,原创 2024-09-04 22:09:59 · 251 阅读 · 0 评论 -
顺序表和链表的优缺点对比
2.CPU高速缓存命中率比较高(CPU通过寄存器在内存中遍历顺序表和链表的过程中,顺序表的速度比较快。数据在寄存器缓存中,称为命中,不在缓存不叫命中。因为顺序表空间连续,如果一次加载16byte,可以把顺序表很多数据都换存进去,但是链表空间不连续,他不太会被一次缓存进去。链表是低命中还存在缓存污染。1.按需求申请内存,需要存一个数据就申请一块内存,也不存在浪费。2.在头部和中间插入数据,需要挪动数据,效率低,O(N)2. 在任意位置O(1)的时间内插入删除数据。1.不支持下标的随机访问。原创 2024-09-10 13:01:24 · 284 阅读 · 0 评论 -
实现支持动态增长的栈和队列
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则(对于同时在栈里面的数据,后进栈的必须先出栈)。如果用单链表作为结构,每次进行数据的头插,让头插的数据作为新的头,为栈顶,让以前进入的数据为栈低。队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数。队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出。出3后,不可能出1,因为2卡着。原创 2024-09-11 18:18:30 · 236 阅读 · 0 评论 -
排序的总结
之前的排序中,都是只能内排序,只有归并排序可以内也可以外排序。归并排序的思想可以应用在外排序中。数组中相同的值排完序以后相对顺序不变就是稳定的,否则是不稳定的。外排序:数据量较大,内存中放不下,数据放到磁盘文件中排序。内排序:数据量相对少一些可以放在内存中排序。冒泡插入归并是稳定排序,其他不是。原创 2024-09-26 19:38:49 · 276 阅读 · 0 评论 -
初始化列表、静态成员、友元
解:创建一个Add类,n是多少就创建大小为n的Add类型的数组,这样在Add的构造函数定义++,对static类型的数据进行++,就可以完成求和。比如Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。),A中可以访问B,B不能访问A。原创 2024-10-11 14:23:35 · 956 阅读 · 0 评论 -
STL-string+题目
string原创 2024-10-16 18:39:27 · 298 阅读 · 0 评论 -
二叉树的链式结构和递归程序的递归流程图
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。链式结构又分为二叉链和三叉链,当前学习二叉链。如果是为了存储数据,线性表更简单,二叉树更复杂,并且插入删除也不好定义。有意义的是通过二叉树引出搜索树,搜索树又有AVL树和红黑树。前中后序的本质是一样的,就是打印的时机不同。深度就是 左边的深度 和 右边的深度 更深的那一个在加1 就是这层现在的深度。原创 2024-09-18 15:17:10 · 655 阅读 · 0 评论 -
内部类、内存管理、malloc和new的差别、模板
内存原创 2024-10-15 20:14:54 · 293 阅读 · 0 评论 -
树的一些内容
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;如上图:B是A的孩子节点。叶节点或终端节点:度为0的节点称为叶节点;子孙:以某节点为根的子树中任一节点都称为该节点的子孙。非终端节点或分支节点:度不为0的节点;兄弟节点:具有相同父节点的节点互称为兄弟节点;节点的祖先:从根到该节点所经分支上的所有节点;节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;节点的度:一个节点含有的子树的个数称为该节点的度;原创 2024-09-12 12:38:26 · 220 阅读 · 0 评论 -
建堆内容的实现
父亲的下标是P,则左孩子的下标为 lc = 2P + 1,右孩子的下标为 rc = 2P + 2。C是左还是右孩子无所谓。因此,堆排序排升序得建大堆。堆排序的时间复杂度是O(longN)。大堆只需要把子节点的大的值选出来往上调就是大堆的构造。堆排序:需要先建堆,排升序建大堆。当数组不是小堆后->创建小堆。原创 2024-09-12 15:56:38 · 186 阅读 · 0 评论 -
二叉树和堆概念
假设度为0的节点有a0个,度为1的节点有a1,度为2的节点有a2个,767 = a0 + a1 + a2 = 2a0 + a1 - 1,如果a1 = 1,则不匹配左边,所以a1 = 0。若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=Log2(n+1). (ps:Log2(n+1)是log以2为。假设度为0的节点有a0个,度为1的节点有a1,度为2的节点有a2个,所以2n = a0+a1+a2。即:K层的树,前K-1层都是满的,只有K层不满,但最后一层是需要从左到右连续的。层数是从1开始数的。原创 2024-09-12 14:24:29 · 687 阅读 · 0 评论 -
域 缺省参数 函数重载 引用 编译链接
如果用C++写的程序提供接口函数给使用者,C++使用者可以直接使用,但如果是一个C使用者调用函数会找不到地址,因为在汇编过程中C使用不修饰的函数名找调用函数,而C++在汇编会产生修饰的函数名,因此无法调用。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。有时候在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern “C”,意思是告诉编译器,将该函数按照C语言规则来编译,不要用C++的规则修饰函数名去编译。原创 2024-09-27 20:03:34 · 1351 阅读 · 0 评论 -
创建日期类、const成员函数、日期类题目
这样去写代码,要声名是在Date类中的。将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。缺省参数在.h文件和.cpp文件中不能都有,一般是在.h的声名中声名缺省值,在.cpp中不写缺省参数。下述代码就直接实现了,不写.h文件的东西。const在*之前修饰的是指针指向的对象,在之后修饰的是指针本身。在下面的代码期望的是const限定this指针指向的内容不被修改。原创 2024-10-10 17:42:13 · 410 阅读 · 0 评论 -
堆排序的实现和TopK问题
2.把剩下的N-K个数据,和堆顶数据进行比较,如果比堆顶的数据小,则替换堆顶的数据,调堆。空间复杂度:O(K)。如果数组的N很大,100亿个数(40个G空间),求K=10前十个最什么的数。堆排序:排升序建大堆,第一步需要先建堆 时间复杂度是O(N)。直接选择排序的时间复杂度O(N^2)。因此整个排序的时间复杂度为堆排序的时间复杂度加上调整的时间复杂度:O(N。在极端情况下,每个点都进行向下调整的话,调整的时间复杂度是O(N。也就是求前K个最大的或者最小的数。最小的K个数来了,一定比堆顶的数大,就可以进堆。原创 2024-09-13 15:30:56 · 314 阅读 · 0 评论 -
类和对象1
和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式是private。类中,使用类数据和方法都封装到一下。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类,这里就是1。原创 2024-09-29 16:43:28 · 952 阅读 · 0 评论 -
二叉树的广度优先遍历和题目
二叉树广度优先遍历利用队列 。typedef char BTDataType;typedef struct BinaryTreeNode{ BTDataType data; struct BinaryTreeNode* left; struct BinaryTreeNode* right;}BTNode;typedef BTNode* QDataType; // 链式结构:表示队列 typedef struct QueueNode { struct QueueNode* ne原创 2024-09-18 18:26:13 · 367 阅读 · 0 评论 -
归并排序,外排序,计数排序(非比较排序)
归并排序:(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。1.最后一个小组归并时,第一个小区间不够gap个,则不需要归并 不处理时OK的 因为他同样满足第二个小区间不存在,因此不处理OK。代码控制中有个gap,gap是1 就是11归(两个相比),gap是2就是22归(四个相比), gap是4就是44归(八个相比)。也就是:假设左边有序,右边有序,然后合并在一起归并后就有序。快排是前序,归并是后续。原创 2024-09-26 17:18:24 · 421 阅读 · 0 评论 -
手写string类+题目
内置类型默认生成的operator=赋值,会完成浅拷贝,自定义类型会去调用它自己的赋值运算。对于string这种需要申请空间的类而言,浅赋值也会导致空间连续释放崩溃,因此也得自己写,销毁原来的空间,开辟一样大的空间,把值拷贝过去。类中自带的拷贝函数是浅拷贝,浅拷贝只是让创建的新的一个名字指向原来地址的内容,这样对于申请空间需要释放空间的类来说,析构的话会导致多次析构同一块内容,会崩溃。但是深拷贝是重新创建一个空间,将原数据拷贝到新空间,再将新空间给你创建的那个新对象,这样自己析构自己的空间,就不会出问题。原创 2024-10-19 19:42:09 · 305 阅读 · 0 评论 -
构造、析构、拷贝构造、赋值运算符重载
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。析构函数:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。构造函数是特殊的成员函数,需要注意的是,构造函数的虽然名称叫构造,但是需要注意的是构造函数的主。类里面的成员函数什么都不写的时候,编译器会自动生成6个成员函数。(可以有多个构造函数)原创 2024-09-29 20:00:50 · 405 阅读 · 0 评论 -
排序(交换排序:快排)
如果是right先走,最坏在遇见left的时候停止,而这个位置是left的位置,值肯定是比key小的,但left先走的话,最坏情况遇见right,此时值是比key大的,交换会出问题。挖坑法:将key的位置看作是一个坑(hole),然后利用part1的思路,找到大的将值放进坑中,然后此时right就是hole,再找小的值,将小的值放进hole中,此时left是坑…理想的情况下:每次排序都是二分,直到二分到最后,那就相当于递归高度次(logN),每一层单趟排都是O(N),时间复杂度O(N。原创 2024-09-25 16:01:52 · 460 阅读 · 0 评论 -
排序(插入,希尔,堆排,冒泡)
直接插入排序:是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。时间复杂度:原数组如果和需要排的顺序逆序的时候是最坏的情况,O(N^2),和冒泡排序时间复杂度相同。蓝色的整体为一组,红色的整体为一组,绿色的整体为一组。每次比较的时候只比较各自颜色指向的数字,以蓝色为例,也就是9,5,8,5相比较后进行排序。gap越大,说明大的数和小的数可以更快的挪到对应的位置,但gap越大越不接近有序。原创 2024-09-24 20:41:28 · 550 阅读 · 0 评论 -
带头双向循环链表
双向带头循环链表每次传一级指针就可以了,因为带头,每次头可以指对方向。ListInsert和ListErase比较好用,可以复用删除和插入所有位置。原创 2024-09-09 17:04:51 · 278 阅读 · 0 评论
分享