算法的分类方法有很多种,其中一些如下所示:
- 实施方法
- 设计方法
- 其他分类
按实施方式分类:
1.递归或迭代
- 递归算法是一种重复调用自身直到满足基本条件的算法。它是 C、C++ 等函数式编程语言中常用的方法。
- 迭代算法使用循环等结构,有时使用堆栈和队列等其他数据结构来解决问题。
- 有些问题适合递归,有些则适合迭代。例如,在递归实现中可以很容易地理解河内塔问题。每个递归版本都有一个迭代版本,反之亦然。
2. 程序性或声明性(非程序性)-
- 在声明式编程语言中,我们说我们想要的,而不必说如何去做。
- 对于过程式编程,我们必须指定获得结果的确切步骤。例如,SQL 更具声明性而不是过程性,因为查询没有指定产生结果的步骤。过程语言的示例包括 C、 PHP和 PERL。
3. 串行或并行或分布式-
- 一般来说,在讨论算法时,我们假设计算机一次执行一条指令。这些被称为串行算法。
- 并行算法利用计算机体系结构一次处理多条指令。他们将问题划分为子问题,并将它们提供给多个处理器或线程。迭代算法通常是并行化的。
- 如果并行算法分布在不同的机器上,那么我们称这种算法为分布式算法。
4. 确定性或非确定性-
- 确定性算法使用预定义的过程解决问题,而非确定性算法通过使用启发式算法在每一步猜测最佳解决方案。
5. 精确或近似-
- 我们能够找到最优解的算法称为精确算法。在计算机科学中,如果我们没有最优解,我们会给出近似算法。
- 近似算法通常与 NP-hard 问题相关联。
按设计方法分类:
另一种对算法进行分类的方法是通过它们的设计方法。
1.贪心法——
- 贪心算法分阶段工作。
- 在每个阶段,都会做出当时好的决定,而不必担心未来的后果。
- 通常,这意味着选择了一些本地最佳。它假设局部最佳选择也有助于全局最优解。
2. 分而治之——
分而治之战略通过以下方式解决问题:
- 划分:将问题分解为子问题,这些子问题本身是同一类型问题的较小实例。
- 递归:递归地解决这些子问题。
- 征服:适当结合他们的答案。
示例:归并排序和二分搜索算法。
3. 动态规划-
- 动态规划 (DP) 和记忆协同工作。 DP和分治法的区别在于,在后者的情况下,子问题之间没有依赖关系,而在DP中,子问题之间会有重叠。通过使用记忆[为已经解决的子问题维护一个表格],DP 将许多问题的指数复杂度降低到多项式复杂度(O(n2)、O(n3) 等)。
- 动态编程和递归之间的区别在于递归调用的记忆。当子问题是独立的并且没有重复时,记忆不会
- 帮助,因此动态规划不是所有问题的解决方案。
- 通过使用记忆[维护已解决的子问题表],动态规划将复杂性从指数降低到多项式。
4. 线性规划-
- 在线性规划中,在输入和最大化(或最小化)输入的某些线性函数方面存在不等式。
- 许多问题(例如:有向图的最大流)可以使用线性规划来讨论。
5.还原【转化与征服】
- 在这种方法中,我们通过将一个困难的问题转换为一个已知问题来解决这个问题,我们有针对该问题的渐近最优算法。在这种方法中,目标是找到一种简化算法,其复杂性不受生成的简化算法的支配。例如,在列表中查找中值的选择算法涉及首先对列表进行排序,然后在排序后的列表中找出中间元素。这些技术也称为变换和征服。
其他分类:
1. 按研究领域分类-
- 在计算机科学中,每个领域都有自己的问题,需要高效的算法。示例:搜索算法、排序算法、合并算法、数值算法、图算法、字符串算法、几何算法、组合算法、机器学习、密码学、并行算法、数据压缩算法、解析技术等。
2. 按复杂度分类-
- 在这种分类中,算法根据它们根据输入大小找到解决方案所花费的时间进行分类。一些算法需要线性时间复杂度 (O(n)),而另一些算法需要指数时间,有些算法永远不会停止。请注意,某些问题可能有多种复杂度不同的算法。
3. 随机算法-
- 一些算法随机做出选择。对于某些问题,最快的解决方案必须涉及随机性。示例:快速排序。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。