引言
算法与数据结构是计算机专业学生的必修课,基础中的基础,所以快速上手,找到学习方向和感觉十分重要。我在学习过程中遇到一本好书,《我的第一本算法书》,把算法讲得很浅显易懂,所以基于这本书的内容,提炼出其中的精华,再加上个人的理解,旨在把最干的干货分享给大家。推荐大家去阅读原书!
算法简介
算法就是计算或者解决问题的步骤。我们可以把它想象成食谱。要想做出特定的料理,就要遵循食谱上的步骤;同理,要想用计算机解决特定的问题,就要遵循算法。但是食谱有时是模糊的, 而算法是严谨的,是能用数学明确描述的。
算法和程序有些相似,区别在于程序是以计算机能够理解的编程语言编写而成的,可以在计算机上运行,而算法是以人类能够理解的方式描述的,用于编写程序之前。不过,在这个过程中到哪里为止是算法、从哪里开始是程序,并没有明确的界限。
就算使用同一个算法,编程语言不同,写出来的程序也不同;即便使用相同的编程语言,写程序的人不同,那么写出来的程序也是不同的。
我们要用计算机能理解的方式构思解法,计算机擅长高速执行一些基本命令,但无法执行复杂的命令。此处的“基本命令”指的是 “做加法”或者“在指定的内存地址上保存数据”等。 计算机是以这些基本命令的组合为基础运行的,面对复杂的操作,也是通过搭配组合这些基本命令来应对的。
如何选择算法
算法的不同会导致其运行时间产生大幅变化,用时间复杂度(是一个可以描述算法运行时间的函数,常用大O符号来表述。)表示。我们使用“步数”来描述运行时间。“1 步”就是计算的基本单位。通过测试“计算从开始到结束总共执行了多少步”来求得算法的运行时间。
下面对这个数列进行一个排序算法:
计n为数列长度,Tc为比较一次的时间,Ts为交换一次的时间,则这个排序算法的时间为:
Tc 和 Ts 都是基本单位,与输入无关。会根据输入变化而变化的只有数列的长度 n,所以接下来只考虑 n 变大的情况。
通过这种表示方法,我们就能大致了解到排序算法的运行时间与输入数据量 n 的平方成正比。
当我们知道选择排序的时间复杂度为 O(n2)、快速排序的时间复杂度为 O(nlogn) 时,很 快能判断出快速排序的运算更为高速。二者的运行时间根据输入 n 产生的变化程度也一目了然。
数据结构简介
数据存储于计算机的内存中。内存如右图所示,形似排成 1 列的箱 子,1 个箱子里存储 1 个数据。 数据存储于内存时,决定了数据顺序和位置关系的便是“数据结构”。
电话簿的数据结构:
- 从上往下顺序添加。
- 按姓名的拼音顺序排列。
数据按获取顺序排列的话,虽然添加数据非常简单,只需要把数据加在最后就可以了,但是在查询时较为麻烦;以拼音顺序来排列的话,虽然在查询上较为简单,但是添加数据时又会比较麻烦。
- 将获取顺序与拼音顺序结合起来。
分别使用不同的表存储不同的拼音首字母,因为各个表中存储的数据依旧是没有规律的,所以查询时仍需从表头开始找起,但比查询整个电话簿来说还是要轻松多了。
将数据存储于内存时,根据使用目的选择合适的数据结构,可以提高内存的利用率。数据在内存中是呈线性排列的,但是我们也可以使用指针等道具,构造出类似“树形”的复杂结构。
链表
链表是数据结构之一,其中的数据呈线性排列。在链表中,数据的添加和删除都较为方便,就是访问比较耗费时间。跟电话簿第一种same。
在链表中,数据一般都是分散存储于内存中的,无须存储在连续空间内。因为数据都是分散存储的,所以如果想要访问数据,只能从第1个数据开始,顺着指针的指向一一往下访问(这便是顺序访问),所以不利于访问,但很方便增减。
下面为顺序访问,增加数据
删除黄色时,绕过它就行,虽然 Yellow 本身还存储在内存中,但是不管从哪里都无法访问这个数据,所以也就没有特意去删除它的必要了。今后需要用到Yellow所在的存储空间时,只要用新数据覆盖掉就可以了。
数组
数组也是数据呈线性排列的一种数据结构。与前一节中的链表不同,在数组中,访问数据十分简单,而添加和删除数据比较耗工夫。与电话簿第二种same!
栈
栈也是一种数据呈线性排列的数据结构,不过在这种结构中,我们只能访问最新添加的数据。后进先出LIFO。
栈只能在一端操作这一点看起来似乎十分不便,但在只需要访问最新数据时,使用它就比较方便了。
队列
队列中的数据也呈线性排列。虽然与栈有些相似,但队列中添加和删除数据的操作分别是在两端进行的。就和“队列”这个名字一样,把它想象成排成一队的人更容易理解。在队列中,处理总是从第一名开始往后进行,而新来的人只能排在队尾。先进先出FIFO。
哈希表
在哈希表这种数据结构中,使用之后介绍的“哈希函数”,可以使数据的查询效率得到显著提升。
所以很像电话簿第三种情况,用多个链表来存储,链表之中顺序访问。
堆
堆是一种图的树形结构,被用于实现“优先队列”(priority queues),优先队列是一种数据结构,可以自由添加数据,但取出数据时要从最小值开始按顺序取出。在堆的树形结构中,各个顶点被称为“结点”(node),数据就存储在这些结点中。
如果需要频繁地从管理的数据中取出最小值,那么使用堆来操作会非常方便。
二叉查找树
二叉查找树(又叫作二叉搜索树或二叉排序树)是一种数据结构,采用了图的树形结构。
所以二叉查找树的最小结点要从顶端开始,往其左下的末端寻找。反过来,二叉查找树的最大结点要从顶端开始,往其右下的末端寻找。
查找也同理,小于就往左找,大于就往右找。
下一篇 !加油!