数据结构与算法
如果你是计算机编程新手,那么首先要学习的内容之一就是数据结构和算法。数据结构和算法是编程的基础知识,每个开发人员和软件工程师都必须掌握。就像你在第一堂数学课上学习代数一样,如果你想成为一名优秀的程序员,学习数据结构和算法至关重要。
在今天的文章中,我们将与您分享关于这两个主题的所有信息。让我们马上开始吧!
什么是数据结构?
数据结构是指以编程方式存储数据,以便能够有效地访问和使用数据。程序员正是通过数据结构,根据程序的目标来引用和操作数据。每个应用程序都会以某种方式使用各种类型的数据结构。
了解不同的数据结构将有助于你了解每种数据结构的工作原理,从而根据当前问题选择合适的数据结构。
数据结构类型
数据结构有很多种,但每个程序员都需要了解的只有六种左右。其中包括以下几种:
线性数据结构
- 数组是最简单的数据结构,它包含相同数据类型的元素。这意味着一个数组不能同时包含整数和字符串,它只能是一种数据类型。数组也用于创建更复杂的数据类型,我将在接下来的段落中介绍。数组中的元素按顺序索引,从 0 开始。
- 栈是一种数据结构,它使用后进先出(LIFO)原则存储元素。简单来说,就是最后放入的元素最先被取出。就像一堆纸一样,最后放入的纸最先会被取出。
- 链表是一种数据结构,其中元素按线性顺序排列且彼此相连。这意味着您必须按顺序访问这些元素,无法进行随机访问。
- 队列这种类型与栈类似,但它不是采用后进先出(LIFO)结构,而是采用先进先出(FIFO)结构。这意味着先添加的元素会先被移除,反之亦然。
非线性数据结构
- 图是一种数据结构,它由节点组成,这些节点通常被称为顶点。每个顶点通过边与其他顶点相连,形成一个结构。
- 树是另一种非线性数据结构,它也由顶点和边组成。与图不同,树数据结构中两个顶点之间只能有一条边。
什么是算法?
在编程中,算法指的是一组用于完成预定义任务的指令。算法并非完整的程序,而仅仅是程序的核心逻辑。算法可以用伪代码等非正式的高级描述来表示,也可以用流程图来表示。
算法的性能取决于两个参数:时间复杂度和空间复杂度。高效的算法执行时间更短,占用的计算机内存空间也更少。代码行数较多的算法通常比代码行数较少的算法占用更多内存。作为程序员,你的目标应该是创建执行时间更短、内存占用更少的算法。
算法的性质
任何算法都必须具备以下性质;
- 输入:算法可以接收零个或多个输入。
- 输出:该算法至少应产生一个输出。
- 明确性:算法的每一步都需要清晰定义。
- 有限性:每个算法都应该只有有限的步骤。
- 正确性:算法的每一步都必须产生正确的输出。
算法类型
算法有很多种类型,但每个程序员都需要了解以下 6 种主要算法;
- 递归算法是指不断调用自身直到问题解决的算法。算法执行必须满足特定条件才会停止。
- 分治算法是一种将解决问题的算法分为两部分:第一部分将问题分解成若干个同类型的子问题;第二部分分别解决这些子问题,然后将所有子问题的解组合起来,最终得到整个问题的解决方案。
- 动态规划算法是一种能够调用上一次运行结果并利用这些结果来寻找下一个解决方案的算法。这类算法会将问题分解成若干个小问题,每个小问题只需解决一次,其解决方案就会被存储起来以供将来使用。动态规划算法通常用于解决优化问题。
- 贪心算法是一种问题求解策略,它在每个阶段都寻求局部最优解,并希望利用这些局部最优解最终找到全局最优解。这种算法通常用于解决需要最大或最小最优结果的优化问题。贪心算法也比较容易实现。一些常见的贪心算法应用包括:CPU调度算法、最小生成树、Dijkstra最短路径算法、内存管理中的Fit算法以及旅行商问题。
- 暴力破解算法是指遍历所有可能的解决方案,以寻找满足特定函数的一个或多个解的算法。你可以把它想象成尝试所有可能的数字组合来破解某个设备的密码。当没有其他算法可以加快解决问题的速度时,通常会使用这种算法,因为此时必须检查所有可能的解决方案才能找到正确的解。
- 回溯算法是一种采用增量方法解决问题的算法。也就是说,如果在某个阶段找不到解决方案,则将其移除,然后回溯寻找另一个解决方案。这类算法通常用于解决决策问题。
如何通过使用正确的算法来提高程序的性能?
正如你在编程学习过程中将会看到的,有些问题可以用我们刚才介绍的任何一种算法来解决。但是,根据你选择的算法类型,性能会有所不同。接下来,我们来看看在选择算法时需要考虑的一些因素。
- 运行时间复杂度是选择合适算法时需要考虑的关键因素之一。在其他条件相同的情况下,总是应该选择运行时间更短的算法。当需要使用多个算法来解决一个大型问题时,时间差异就显得尤为重要。
- 内存消耗:这些算法的应用场景通常计算资源有限。因此,选择占用内存空间较小的算法类型至关重要。内存空间通常取决于算法解决当前问题所需的输入数据量。
- 并行处理:如果问题需要并行处理以加快执行速度,那么理想的算法是将问题分解成若干个可以独立求解的子问题,然后将这些子问题的解组合起来,形成大问题的整体解。在这种情况下,分治算法始终是最佳选择。
- 精度要求:首先,你需要分析问题,确定算法输出结果需要达到怎样的精度才能解决当前问题。然后,你应该选择在可接受的精度范围内,运行速度最快的算法。
学习资料
-
精选了一些学习和/或练习算法的好去处:
https://github.com/tayllan/awesome-algorithms -
为了巩固你的算法和数据结构知识,你可以使用以下资源:
https://www.hackerrank.com
https://leetcode.com/
最后想说的
关于数据结构和算法,还有很多东西值得学习。我们分享的基础知识可以作为学习这两个主题的跳板。你需要深入研究不同类型的数据结构,才能弄清楚何时使用哪种数据结构,以及你的选择会对程序的性能产生什么影响。
本文并未涵盖所有更具体的具体数据结构和算法类型。不过,我们讨论的都是你在编程学习过程中经常会遇到的常见类型。
文章来源:https://dev.to/firdavs_kasymov/data-structs-and-algorithms-4pd0