- 博客(27)
- 收藏
- 关注
原创 oi~,让我告诉你如何实现哈希表
假设M为 2^3,这相当于直接保留了2进制中的后3位,那么只要key值的后3位相同那么就一定冲突,例如:3,11,19,27......,它们二进制的后三位都是011,所以它们同时取余M都等于3。同理当M为10的幂时,假设为10^3,这相当于保留了10进制中的后3位,那么只要key值的后3位相同就一定冲突,例如:1001,2001,3001.....,所以也不可取。如图,如果这里我们删除30这个值,后续查找时发现20这个值冲突,根据插入规则,我们会去往后面找,当找到空时查找停止,查找20就会失败。
2025-04-10 22:15:24
869
42
原创 封装红黑树实现map和set
之前我们学习了set与map容器的如何使用,红黑树的实现。接下来我们来看看如何通过封装红黑树,实现我们自己的set与map。
2025-04-09 22:28:22
732
27
原创 map容器练习:使用map容器识别统计单词个数
2.因为map是按照字典序排序的,所以我们需要按照单词个数重新排序,map本身是不支持sort,所以我们将map的数据放入vector中进行排序(pair本身是支持排序的,但是它支持的排序,并不是我们所需要的排序,所以我们要传入仿函数实现自己定义的排序)输入一个英文句子,把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来,次数一样的按照单词小写的字典序排序输出,要求能识别英文单词和句号。得到单词与其个数,我们会用到map容器。输出要求:个数多的先输出,个数相同按照字典序排序输出。
2025-03-17 15:35:02
745
52
原创 使用位运算如何找到数组中只出现一次的数?
位运算是用于二进制的运算符号。而对于多次出现的数字,其二进制都是一模一样的,这里是3次重复的出现是数字。由此我们可以想到,如果我们。其实对于这种题:一个元素只出现一次,其余元素出现n次。方法是一样的,只需要。如果为0则代表这个bit位上都是重复出现的数字。如果位1则代表出现的我们要找的数字。由低到高去计算为一个bit位上的和。,再去计算和判断下一个bit位。将取余3改为取余n即可。
2025-03-13 16:36:26
368
38
原创 oi!让我来给你唠唠咋实现红黑树☝️
先旋转在将p变为黑,pp变为红,使其满足规则。这样调整过后p变成了新的”根”节点,且为黑色,而黑色节点不论p的上一层是黑色还是红色都符合规则。所以旋转+变色后就结束调整。(在旋转过程中,因为这里是三叉链要注意_parent指针的更新,详细可参考具体的实现代码)先p点旋转,再pp点旋转,最后cue变黑色 pp变红色。这样调整过后cur变成了新的”根”节点,且为黑色,而黑色节点不论cur的上一层是黑色还是红色都符合规则。所以旋转+变色后就结束调整。(在旋转过程中,因为这里是三叉链要。
2025-03-10 21:46:03
954
33
原创 不使用加减运算符,如何实现两个数相加?
可能会些朋友第一次遇见这个题比较困惑,真能不用加减法得到两个数的和吗?这简直是太匪夷所思了,真的有这种方法吗?欸!🤓☝️有的朋友有的。
2025-03-08 13:00:00
478
16
原创 让我来告诉你如何实现AVL树(C++)
完整代码如下// 需要parent指针,后续更新平衡因子可以看到int _bf;// balance factor 平衡因子:_kv(kv), _bf(0){}public:while(cur)if (cur->_kv.first > kv.first) //pair重载了大小于运算符elseelse//连接到父亲节点//控制平衡//更新平衡因子elsebreak;//进行旋转。
2025-03-06 17:34:08
620
16
原创 超详细介绍map(multimap)的使用
红黑树的节点类型是pair类型,使用pair<Key,T>存储数据T1 first;T2 second;{}{}{}
2025-02-24 23:09:42
455
6
原创 超详细介绍set(multiset)的使用(C++)
set的声明如下,T为set的底层关键字set默认要求T支持小于比较,若不支持或者自己想实现其他比较,可以自己写仿函数传给第二个参数set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参数一般情况下,我们是不需要传后两个参数的set的底层是由红黑树(既平衡二叉树)实现的,增删查的效率是logN,迭代器遍历走的是二叉树的中序遍历,所以是有序的。
2025-02-21 17:06:43
352
7
原创 二叉搜索树的实现(C++)
二叉搜索树(搜索二叉树,Binary search tree)是一种特殊的二叉树。其规则为:左子树的值一定小于等于根,右子树的值一定大于等于根,并且左右子树也为搜索二叉树。
2025-02-16 22:58:00
378
8
原创 优选算法:长度最小的子数组(滑动窗口)
如图,当left,right找到了大于等于目标值的情况,先记录长度。然后作为暴力解法的话就是,left++,right=left+1。这里的话仔细看我们会发现没必要,当大于等于目标和时,我们。首先,我们还是定义两个指针left right 进行搜索然后相加,然后比较。这听起来好像和暴力解法没区别吧?既两个for循环暴力相加来判断,毫无疑问暴力解法肯定会超时,题意为:给一个数组,找其中元素相加>=目标值的最小子数组(子数组是连续的),然后判断移动后的结果:如果仍是大于等于目标值,记录长度,left++。
2024-11-25 13:05:41
477
10
原创 优选算法:三数目标之和(双指针)
如上图所示,我们定义出两个指针 left right,利用循环判断 fix+left+right值与0的关系。直到left 与 right相遇时,fix位置的情况考虑完毕,fix++,进入新的大循环。如图(红色箭头)此时满足条件压入ret后,left++ right--,我们发现left指向的仍是1 right指向的仍是3,这种情况我们是已经计算过了的不能再次压入栈,所以我们可以。然后这里是求三个元素相加的和,如果三个动态的我们是不太好考虑的,所有我们可以先固定一个数,然后只考虑两个动态的数,
2024-11-17 23:41:52
1020
5
原创 优选算法:两数目标和(双指针)
首先,我们直接来一个sort函数,对整个数组进行排序。然后定义出两个指针 left 与 right,left指向最左边,right指向最右边。最后通过循环判断 如果left+right==目标值,直接返回。如果>目标值,则right-- 继续判断。如果
2024-11-17 22:45:05
457
3
原创 优选算法:有效三角形的个数(双指针)
说明这三个元素构成三角形,并且left左边的元素加上right都是大于max的,所以从这里我们可以直接得到这个范围下有 right-left 的三角形。此时需考虑下一个范围的情况,而移动left是没有意义的(因为这种情况我们已经计算过了),故而right--,进入新的循环进行判断。我们先选择最右边(max)的元素作为固定边(进过sort排序最右边为最大的元素),再从max的右边(left,right)的区域去选择元素。给出一个数组,要求找出数组中所有可以组成三角形的元素的组数。则max--,再进入新循环。
2024-11-16 19:47:35
658
1
原创 优选算法:盛水最多的容器(双指针)
我们不妨直接定义出两个指针 left right 分别放在数组的最左边和最右边,先得到容积v1。然后再得到新区域的容积v2,再改变较小的边界。题目给我们一个数组,我们要在数组中任意两个元素作为容器的的高(高为最小的为准)两个元素的间隔作为容器的底 的情况下,找到最大的容积(底 * 高)(改变右边界时,高一定是小于等于left的,而宽也在减小)。我们的题目是再求最大,所以这个情况就不必再去计算直接排除。改变最左边界(较小边),是可能出现大于v1的情况的。改变两边中较大的一边是没有意义的。
2024-11-15 23:23:44
473
2
原创 优选算法:快乐数(双指针)
然后判断此时快慢指针指向的元素是否为1,若是则为快乐数,反之不是。这就不由的让我们想到带环问题,对于带环问题我们可以记住一个结论性的东西:在带环问题中,我们可以定义出两个指针(快慢指针:快指针一次走两步,慢指针一次走一步)不论这两个指针相隔多远,最后一定会在环里面相遇。将一个正整数的每位数的平方相加得到一个新数,再将得到的新数按相同的方法,再得到一个新数........ 由此不断的下去。这样的操作会得到两种情况:1.得到1的无穷循环(因为通过1得到的新数仍然还是1),2.得到非1的无穷循环。
2024-11-15 22:22:42
451
2
原创 优选算法:复写零(双指针)
那肯定是因为此时cur指向的元素要复写两次,如果此元素只需要复写一次的话根本不会超出范围。那肯定是0,所以我们需要做的处理就是:将数组最后一个元素修改为0,然后再将cur--,dest-=2,手动的帮它完成复写工作。当cur指向元素为非0元素则dest++,为0元素则dest+=2。那么从cur位置开始从后向前遍历,cur指向元素为非0元素时 数组[dest]=数组[cur] 然后dest--,cur--。首先如果我们选择从前向后复写,那么前面复写的元素则会覆盖后面需要复写的数,这样行不通。
2024-11-14 12:03:41
311
4
原创 优选算法:移动零(双指针)
当cur遍历到0元素时,不需要做任何处理直接++,因为这样这个0元素正好直接进入dest的右边,这也正好满足我们的预期。当cur非0元素时,我们是需要非0元素进入dest的左边的,所以我们应该先让dest++ 给新进来的元素腾出位置,然后交换两个元素。cur用于遍历整个数组,cur左边代表以及被遍历了(或说已经被处理过了)右边代表未遍历(未处理)。而dest则是用于定于cur左边区域(已经处理过的区域)中第一个0的前一个位置,通俗的说dest的作用就是非0元素 与 0元素的分界线。
2024-11-13 21:32:19
462
4
原创 关于printf函数(详解)
限制了小数的位数只能保留小数点后两个位,并且还会进行4舍5入。因为这里我们说了是限制的最小宽度,而不是最大宽度。可以使用符号 ‘ * ’来代替。小数点 也占了一个宽度。
2024-02-29 19:04:52
646
3
原创 原码 反码 补码
值得一提的是:对于计算机来说,不论是整数数据的存放还是运算,计算机都是以补码的形式进行计算或存放的。补码 先取反 再+1(或者先-1 再取反)得到原码。总结:原码取反--->反码,反码+1--->补码。
2024-02-26 18:20:46
151
4
原创 特殊转义字符(\ddd,\xdd)
此外值得注意的是我们不论使用\ddd还是\xdd,我们都要注意其转化为10进制的数字不能超过ascell码的范围(0~127)
2024-02-06 11:35:25
658
6
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人