
c++数据结构与算法
文章平均质量分 77
介绍c++数据结构与算法相关知识
赵鑫亿
c++数据结构与算法,python 爬虫,web 开发
展开
-
前缀和and哈希表的巧妙配合
前缀和算法是一种在数组处理中非常实用的算法技巧,它能够高效地解决很多与区间和相关的问题。下面从基本概念、使用场景、实现方式以及具体示例等方面来详细介绍前缀和算法。原创 2025-03-24 22:56:03 · 957 阅读 · 0 评论 -
12.3单源最短路及差分约束系统
问题类型核心算法应用场景注意事项单源最短路(正权)Dijkstra路径规划、网络路由优先队列优化提升效率单源最短路(含负权)差分约束、金融模型必须检测负权环差分约束系统SPFA任务调度、资源分配构造边时注意不等式方向转换。原创 2025-02-23 10:17:13 · 462 阅读 · 0 评论 -
12.4拓扑序列
环检测:两种算法均能检测环,Kahn通过结果长度,DFS通过递归路径。顶点表示:通常用整数编号(0到n-1),便于数组索引。扩展性:若需字典序最小拓扑排序,Kahn算法中将队列改为优先队列。通过理解这两种实现方式,您可以根据实际需求选择最适合的拓扑排序策略。原创 2025-02-22 16:24:16 · 931 阅读 · 0 评论 -
12.2最小生成树
在加权连通图中,连接所有顶点的树形结构,且所有边的权值之和最小。原创 2025-02-20 17:28:06 · 667 阅读 · 0 评论 -
12.1欧拉回路
【代码】12.1欧拉回路。原创 2025-02-17 15:45:06 · 527 阅读 · 0 评论 -
10.3字符串manacher算法
理解Manacher算法的关键在于掌握其利用回文对称性避免重复计算的策略,以及通过预处理统一处理奇偶长度的巧妙设计。该算法体现了计算机科学中空间换时间和利用已知信息优化计算的思想。Manacher算法是用于在O(n)时间复杂度内查找字符串中最长回文子串的高效算法。处理后的字符串:^ # a # b # b # a # $原创 2025-02-16 13:50:08 · 500 阅读 · 0 评论 -
10.2字符串kmp算法
对于模式串P,next[i]表示子串P[0…i]中最长的相等真前缀和真后缀的长度(不包括自身)模式串:A B A B C索引: 0 1 2 3 4。原创 2025-02-14 11:33:37 · 348 阅读 · 0 评论 -
10.1字符串哈希
在使用// 使用FNV-1a算法uint8_t(c);// 使用示例默认选择:多数情况下已足够高效。自定义场景:根据数据特性选择或实现特定哈希函数。性能与碰撞:权衡速度和碰撞率,必要时进行碰撞测试。跨平台与安全:通过明确哈希实现确保一致性,高风险场景使用安全哈希。通过理解不同哈希算法的原理与适用场景,开发者能够针对具体需求优化C++程序中的字符串处理性能与可靠性。原创 2025-02-14 11:31:38 · 800 阅读 · 0 评论 -
9.7启发式搜索
通过合理设计启发函数和优化实现,启发式搜索能有效解决复杂路径规划、决策优化等问题。A*算法及其变种已成为游戏开发、机器人导航等领域的核心技术,掌握其原理与实现对算法工程师至关重要。h(n) ) (加权A。原创 2025-02-13 17:34:52 · 723 阅读 · 0 评论 -
9.6迭代加深搜索
通过这种深度受限的搜索策略,IDS在保证空间效率的同时,获得了与BFS相当的解决方案质量,是处理复杂状态空间问题的利器。通过逐层增加深度限制,在每一层进行深度优先搜索,直到找到解。:在棋盘类问题中优先展开有希望的方向。*:结合启发式函数的迭代加深算法。:同时从起点和终点进行迭代加深。迭代加深搜索(IDS)是一种。:记录已访问状态避免重复搜索。:在不同深度层使用多线程搜索。原创 2025-02-13 17:34:17 · 684 阅读 · 0 评论 -
9.5记忆化搜索
记忆化搜索通过缓存子问题结果,显著提升递归算法效率,适用于具有重叠子问题的场景。在C++中灵活运用数组或哈希表存储状态,能有效解决复杂问题如动态规划、组合优化等。原创 2025-02-13 17:33:28 · 671 阅读 · 0 评论 -
9.4双向BFS
(Bidirectional BFS)是一种优化策略,通过,在中间相遇时终止搜索。(b为分支因子,d为起点到终点的深度)原创 2025-02-12 17:00:44 · 608 阅读 · 0 评论 -
9.3剪枝优化策略
是一种优化策略,用于在搜索过程中。原创 2025-02-11 11:08:02 · 726 阅读 · 0 评论 -
9.2DFS
如果需要具体应用场景的代码实现(如拓扑排序或迷宫求解),可以告诉我具体需求,我可以提供对应的代码模板和解析。Depth-First Search(深度优先搜索)是一种。用于检测环路和进行拓扑排序。原创 2025-02-10 14:51:47 · 705 阅读 · 0 评论 -
9.1BFS
Breadth-First Search(广度优先搜索)是一种。原创 2025-02-09 11:21:10 · 1236 阅读 · 0 评论 -
8.高精度算法
通过系统化的字符串操作和逐位模拟,高精度算法能够准确处理超大数运算问题。开发者可根据实际需求扩展功能或优化性能。的实现思路,并提供完整代码和测试示例。所有算法均基于字符串操作,支持。高精度算法用于处理超出标准数据类型范围的数值运算。原创 2025-02-08 10:50:53 · 638 阅读 · 0 评论 -
7.5数位DP
数位动态规划(Digit DP)是一种专门用于解决与数字各位相关的计数问题的算法,常见于统计满足特定条件的数字个数(如不含某些数字、各位之和限制等)。以下通过具体示例(统计区间。通过系统化的状态设计和记忆化搜索,数位DP能够高效解决复杂的数字计数问题。理解其核心思想后,可灵活应用于各类变种问题。(对应数字:5, 14, 23, 32, 41, 50),求该区间内所有各位数字之和等于。的数字个数)详细讲解其实现。转换为字符串,便于逐位处理。原创 2025-02-07 21:42:09 · 278 阅读 · 0 评论 -
C++实现所有算法!看这一篇就够了!新手小白、技术大佬均适用!
本篇文章涵盖了用C++实现的所有基本算法,可以用来构建自己的算法库,在自己的源代码中直接调用即可,对新手或者不关心代码内在逻辑的同学十分友好。至于想了解具体算法实现的也可以往下看,在最下面会对每个算法进行解释与分析。排序算法:冒泡排序、快速排序、插入排序、选择排序、归并排序、堆排序、希尔排序、计数排序、桶排序、基数排序搜索算法:线性搜索、二分搜索、插值搜索、斐波那契搜索树结构搜索算法:深度优先搜索(DFS)、广度优先搜索(BFS)、二叉搜索树(BST)搜索、A* 算法图搜索算法:迪杰斯特拉(原创 2025-02-07 14:41:13 · 1755 阅读 · 0 评论 -
7.4状压DP
其核心思想是将多维状态压缩为整数,利用位操作快速进行状态转移。提前计算必要信息(如字符串重叠长度、冲突关系),避免在DP循环中重复计算。先掌握基础状态表示(如子集选择),再挑战复杂问题(如TSP)。跳过不可能达到更优解的状态(如当前路径已超过已知最短长度)。利用问题对称性减少状态数量(如旋转、镜像对称的棋盘状态)。是一个二进制整数,表示当前已选/已访问的元素组合。时,考虑其他算法(如启发式搜索)或问题特定优化。:用位掩码表示列、主对角线、副对角线的占用情况。分析状态转移的物理意义,避免盲目套用模板。原创 2025-02-06 22:35:11 · 1052 阅读 · 0 评论 -
7.3.树状DP
是一种基于树形结构的动态规划方法,常用于解决子树相关的最优化或计数问题。其核心思想是通过递归遍历树的节点,自底向上(后序遍历)或自顶向下传递状态信息,结合子节点的解推导父节点的解。:用最少的摄像头覆盖所有节点,摄像头可以监视父节点、自身和直接子节点。:在二叉树结构的房屋中,不能同时偷相邻节点,求最大偷窃金额。:求二叉树中两个节点之间的最长路径(可能不经过根节点)。:找到二叉树中任意节点间的路径,使得路径和最大。确定叶子节点或空节点的状态初始值(如叶子节点的。为起点的单侧最大路径和,同时更新全局最大值。原创 2025-02-05 15:27:28 · 1016 阅读 · 0 评论 -
7.2.背包DP
是解决资源分配类问题的核心算法范式,尤其在处理物品选择与容量限制的组合优化问题时表现优异。,并通过大量练习熟悉不同变种的解题模式。建议从标准0-1背包入手,逐步扩展到更复杂的变种。物品可无限次选取,求装满背包的最大价值。物品被分为多组,每组只能选一个物品。转化为0-1背包:找是否能凑出。(与0-1背包的唯一区别是。,求能装入的最大总价值。掌握背包DP的关键在于。原创 2025-02-04 21:55:36 · 1025 阅读 · 0 评论 -
7.1.普通一维DP问题
在C++中,一维动态规划(1D DP)是处理线性序列问题的核心方法。这类问题的状态通常只依赖前一两个状态,可以用一维数组(或变量)存储中间结果。以下是详细解析:明确问题是否满足DP条件定义状态确定初始条件推导状态转移方程选择遍历顺序空间优化(可选)问题:计算第个斐波那契数()状态定义:表示第个斐波那契数状态转移:2. 爬楼梯问题(LeetCode 70)问题:每次爬1或2阶台阶,到达第阶有多少种方法?状态定义:表示到达第阶的方法数状态转移:(最后一步可能是1阶或2阶)3. 打家劫舍(Le原创 2025-02-03 16:06:40 · 1113 阅读 · 0 评论 -
7.DP算法
和。原创 2025-02-02 20:02:57 · 1277 阅读 · 0 评论 -
6.二分算法
二分算法,也称为二分查找或折半查找,是一种在有序数组中查找特定元素的高效算法。C++在STL库中已经封装好了二分算法,我们只需要引入调用即可。原创 2025-01-31 13:39:17 · 461 阅读 · 0 评论 -
5.模拟算法
模拟算法就是按照实际问题的逻辑和规则,用计算机程序来模拟事物的变化过程和状态,从而解决问题或获得对问题的理解。它通常需要根据问题的具体情况,定义数据结构来表示问题中的各种元素和状态,然后通过一系列的操作和逻辑来模拟这些元素和状态随时间或其他因素的变化。第一行包含三个整数:N,N_A,N_B,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。第二行包含 N_A 个整数,表示小 A 出拳的规律,第三行包含 N_B 个整数,表示小 B 出拳的规律。次项的系数,每两个整数之间用空格隔开。原创 2025-01-25 15:20:20 · 1364 阅读 · 0 评论 -
4.贪心算法
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解,如单源最短路径问题、最小生成树问题等。原创 2025-01-24 13:47:49 · 1523 阅读 · 0 评论 -
3.10.平衡树
定义:平衡树是一种二叉搜索树,它在满足二叉搜索树性质(左子树节点值小于根节点值,右子树节点值大于根节点值)的基础上,通过特定的算法和操作,确保树的左右子树高度差在一定范围内,从而保持树的 “平衡” 状态。特点高度平衡:这是平衡树最主要的特点,通过调整节点的位置和连接关系,使得树的高度尽可能低,一般来说,高度与节点数 的关系为。高效的操作:由于高度平衡,在平衡树上进行插入、删除和查找等操作的时间复杂度都能保持在 级别,相比普通的二叉搜索树,在最坏情况下性能有很大提升。原创 2025-01-23 14:42:21 · 918 阅读 · 0 评论 -
3.9.并查集
【代码】3.9.并查集。原创 2025-01-22 15:21:43 · 282 阅读 · 0 评论 -
3.8.Trie树
定义Trie 树是一种树形结构,每个节点可以包含多个子节点,用于存储字符串集合。它的每个节点代表一个字符串的前缀,从根节点到任意节点的路径上的字符连接起来,就形成了一个字符串。原理Trie 树利用字符串的公共前缀来减少存储空间和提高检索效率。在插入和查找字符串时,从根节点开始,沿着与字符串中字符对应的子节点向下遍历,直到到达字符串的末尾或者无法继续匹配为止。在 C++ 中,通常使用结构体或类来定义Trie 树的节点。原创 2025-01-21 15:39:26 · 1137 阅读 · 0 评论 -
3.7.线段树
线段树是一种二叉树数据结构,主要用于解决区间查询和更新问题,例如区间求和、区间最大值、区间最小值等。它将一个数组的元素存储在树的叶子节点上,而每个内部节点表示一个区间的统计信息(如该区间的和、最大值、最小值等),该区间是其左右子节点所代表区间的并集。对于更复杂的操作,如区间乘法、区间更新等,可以相应地修改节点存储的信息和更新逻辑。线段树在处理需要频繁更新和查询区间信息的问题时非常有效,时间复杂度通常为 ,比朴素的数组操作()更高效。以下是区间查询的代码示例,用于查询区间。的线段树,数组的空间为。原创 2025-01-19 13:55:23 · 565 阅读 · 0 评论 -
3.6.树状数组
树状数组(Binary Indexed Tree,简称 BIT)是一种高效的数据结构,它可以在O(log n)的时间复杂度下实现对数组的单点更新和区间求和操作。使用树状数组可以有效地解决一些动态更新和区间求和的问题,提高程序的运行效率,尤其是在数据规模较大时,它能显著降低时间复杂度。当更新数组中某个元素的值时,需要更新树状数组中与之相关的节点。开始,不断向下查找子节点,将结果累加,查找的规则是将。开始,不断向上更新父节点,更新的规则是将。的和,我们只需要分别求出区间。,直到超出数组范围。原创 2025-01-18 15:17:52 · 469 阅读 · 0 评论 -
3.5.堆
定义:堆是一棵完全二叉树,通常用数组来实现。堆中的每个节点都满足堆的性质。性质最大堆:对于每个节点,其值都大于或等于其子节点的值。根节点是堆中的最大值。最小堆:对于每个节点,其值都小于或等于其子节点的值。根节点是堆中的最小值。原创 2025-01-17 16:21:46 · 876 阅读 · 0 评论 -
3.4.ST表
在 C++ 中,ST 表(Sparse Table)是一种用于解决区间最值问题的数据结构,它基于倍增思想,能在O(n log n)的时间复杂度内完成预处理,之后以O(1)的时间复杂度查询区间最值。ST 表是一种非常高效的数据结构,尤其适用于需要频繁查询区间最值且数据不频繁修改的场景。它利用倍增思想,在预处理阶段做了充分的准备,使得后续的查询操作非常迅速。首先,我们需要对 ST 表进行初始化。接下来是查询操作,假设我们要查询区间。原创 2025-01-16 21:05:05 · 935 阅读 · 0 评论 -
3.3.队列
上述的三种方法实现队列中,使用数组实现的队列为循环队列,最大容量为MAX_SIZE,使用链表和vector实现的队列则可以动态扩容。无论哪种方法实现队列,复杂度都是O(1),非常高效。那么同栈一样,c++的STL库中一样提供了queue库来供我们直接使用,下面一起来看看吧。原创 2025-01-14 13:43:14 · 1049 阅读 · 0 评论 -
3.2.栈
分析输入,我们可以发现除掉第一个数字,后面的形式全部都是一个符号加一个数字,那么我们可以选择先将第一个数字压入栈,再循环输入后面的内容,进行对应的操作。这道题毫无疑问得用栈的知识,先把输入的数字压入栈,然后根据它后面的符号再对栈顶进行对应的操作,如果是。栈是一个带有限制的表,它的插入和删除都只能在一个位置上进行,即只能在表的末端进行,这个末端叫。对于一个栈,我们能操作的只有栈顶。号就直接压入栈,最后栈中的数字全都是相加处理,直接全部相加得到结果。号,就对栈顶和输入的数字做相乘处理,再把结果压入栈,如果是。原创 2025-01-11 12:55:09 · 809 阅读 · 0 评论 -
2.6.桶排序
第二步,对数组进行计数,计得的数存储到桶中,也就是把元素的大小当作桶的索引,从这里就可以看出来,桶的大小取决于数组中元素的最大值,而在传参的时候也要传入一个参数为数组中元素的最大值。具体桶的个数取决于数组中元素的大小,所谓桶其实也是一个数组,只不过桶的索引代表数组的元素,而索引值代表在原数组中此元素的个数,例如对于需要排序的数组{1,2,3,5}而言,需要创建一个桶,计数完成后为{0,1,1,1,0,1}桶排序也是一种非常快的排序算法,但是对于个别数组中某个元素比较大的情况比较费内存。原创 2025-01-11 10:41:03 · 265 阅读 · 0 评论 -
3.1.链表
数组在删除和插入元素的时候,最坏的情况是删除和插入第一个元素,这样要把整个数组的所有元素前移或者后移一位,复杂度为O(n),最好的情况是删除和插入最后一个元素,复杂度为O(1),平均复杂度也为O(n/2)=O(n)。单向循环链表就是把最后一个节点的指针指向第一个节点,双向循环链表就是把第一个节点的前指针指向最后一个节点,最后一个节点的后指针指向第一个节点,这里就不进行画图演示了。也是单向链表,每个节点包含一个数据和一个指向下一个节点的指针,最后一个节点的指针指向。原创 2025-01-10 14:08:53 · 768 阅读 · 0 评论 -
3.0.ADT
抽象数据类型是数学的抽象,在ADT的定义中并没有局限ADT的操作具体怎么实现,所以像表、集合、图以及他们各自的操作一起形成的对象都可以看作ADT。可以看到,表是下面几个数据类型的基本思想,而真正可以直接使用的只有数组arr,Vector,List,而链表作为表的一种衍生思想,同样也是无法直接使用的。至于我们所熟知的表,链表,数组,vector,list等的关系,我画了一张图,帮助大家了解它们到底分别是什么。而实现ADT的基础,就是表,这里的表可不是STL中的list,就叫做表。原创 2025-01-10 14:05:24 · 876 阅读 · 0 评论 -
2.8.基数排序
有的,以上面的例子来说,个位相同的数字可能没有,也可能1个,2个,3个甚至更多,那么按一个元素占一个位置来说,个位相同的两个元素就得占两个位置,类比到这里,例如,个位为0的一个元素占第一位,个位为1的元素没有,此时指针仍然指在新数组第一位,个位为2的元素有1个,占新数组的第二位,个位为5的也一样,一直到个位为6的元素,有两个,那么第四位,第五位都是属于个位为6的元素的,后面以此类推。基数排序主要分为两个大步骤:计数和排序,其中计数可能是多次的,具体的次数取决于待排序的数组中最大的数字的位数。原创 2025-01-09 20:49:47 · 633 阅读 · 0 评论 -
2.7.堆排序
第二个for循环用作给已经建好堆排序,使用的思想其实就是前面优先队列的思想,只不过我们为了避免新开数组增加空间复杂度,我们把已经排好序的元素填充到空出来的位置,对于大根堆而言,第一次swap操作就让数组中最大的元素,同时也是位于根节点的元素跑到数组的最后一位,接着对剩下的元素再重新建堆,得到根节点的元素是剩下元素中最大的,再把它放到数组的倒数第二位,以此类推,直到最后一个元素移动到根节点,排序完成。堆是一颗被完全填满的二叉树,而可能例外的底层的元素则是从左往右依次填入,比如下面就是一个堆。原创 2025-01-07 21:45:08 · 732 阅读 · 0 评论