打算把数据结构跟算法的知识捋一捋,所以新建了个文集。
很多人都说这是内功,那学这个到底有什么用呢,我找了几篇蛮有道理的文章转了过来,来坚定下学习的信念。
我看完这几篇后觉得,学这个最重要的是学会了把现实中的实际问题抽象为计算机能够理解的数据模型,然后施加以算法以解决问题。
找的文章如下:
作者:刘欣
链接:https://www.zhihu.com/question/29587605/answer/147424220
来源:知乎
《数据结构》是计算机专业的一门必修课, 可是很多学生学完以后,觉得用处不大, 还不如学个C,Java来的直接一点。
等到工作了以后做业务系统开发,发现根本就用不到那些书中的讲的二叉树、图、排序算法, 更加觉得这门课是在浪费时间了。
这种想法实际上是错误的。
学习数据结构,并不仅仅是学习其中现成的那些队列,堆栈,二叉树,图等经典结构, 也不仅仅是学习其中的那些快速排序、冒泡排序等算法。
更重要的是你要学习一种思想:如何把现实问题转化为计算机语言的表示。
计算机其实一种很笨,很机械的机器,只会按照预定的指令一步步执行, 而计算机语言的特点就是精确、无二意, 它的本质语言是二进制的, 即使是C,Java等高级一点的语言也只不过是包装而已, 它的表达能力并没有本质的提升, 仍然停留在很低的层次。
而我们用的自然语言则是典型的模糊的,不精确的, 程序员面临的一个重要问题, 或者是我们的主要工作就是怎么把自然语言描述的问题转化为计算机语言的表示。
到底该怎么转化, 《数据结构》已经给出了指引: 设计出数据结构, 在施加以算法就行了, 当然现实问题会更复杂, 需要框架,类库,模式等支撑。
这是一种非常重要的逻辑思维能力的锻炼, 也是程序员入门的条件。
很多半路出家的人, 仅仅上了个培训班后参加工作, 写出的代码实在是惨不忍睹, 很明显只掌握了工具,逻辑思维的训练远远不足。
就我个人而言, 大学时学《数据结构》以后, 为了准备高级程序员考试, 把里边的习题全部做了一遍, 发现真是受益匪浅, 不但高程的成绩非常好, 更重要的是在后来的工作中,遇到数据结构相关的实际问题, 基本上没有什么障碍,只要掌握了语言特性, 解决起来非常轻松。
总结一下,《数据结构》这门课其实会潜移默化的影响你的逻辑思维, 当然, 你需要多多练习才有可能使用纯熟, 等它变成身体一部分以后, 你就发现其实大部分编程任务都没什么难度了,更难的其实是对编程更高的要求:抽象的能力。
作者:吕双全
链接:https://www.zhihu.com/question/29587605/answer/71567673
来源:知乎
想从“由顶向下”的角度说说自己浅显的理解:
我们知道计算机是人类在思考“能不能偷懒”的原始欲望下创造出来——找一个自动、快速、不知疲惫地替人类进行各种工作的机器。在有了诸如“图灵机”等计算模型理论的支撑下,人们找到了通用的底层方式来实现自己想要功能的方法。但这些方法需要让计算机理解——或者可以被处理后理解,就需要我们以某种形式,将我们的问题一步步抽象、一步步化简,直到形成某种计算机可以理解的“程式化”的语言或组织形式,最后对计算机说一句:剩下的就交给你了!
举个不甚恰当的例子:
比如我们计划去旅游,我们手里有地图,想知道计划中的几个城市直接是否都有高速公路可以走,从而不会有某个城市因道路不通而无法驱车前往。虽然我们可以自己去查,但是我们有计算机啊!于是我们想借助它来完成这个任务,于是进行了第一步抽象——将城市表示为一个个点,道路表示为边,结合起来形成了叫图的数据结构。我们想知道的便是——这张图是否是一个连通图?比如我们用1、2、3、4分别表示“北上广深”(仅作意会),线段表示道路,于是有了这张图:
画出来以后,我们自己心里明白它表示什么,但计算机不懂。于是我们进行第二步抽象——将图编码,转化为计算机可以编译的语言。于是得到下面表示方式:
<G> = (1,2,3,4) ((1,2),(2,3),(3,1),(1,4))
前面括号中我们用数字表示各个节点(对应“城市”)的编号,后面则用“(节点,节点)”成对的形式表示一条边(对应 “道路”)。
那么计算机如何处理呢?这时就需要设计一种算法,告诉它怎么理解和处理人类跟你说的话。比如可以按这样的方式:
- 选择第一个节点并进行标记。
- 重复第3步直到没有新的节点可以被标记。
- 对于G中的每个节点Ni,如果有一条边与其相连,且边的另一头是一个已经被标记的节点Nj(i不等于j),那么将Ni进行标记。(这一步要借助上面写出的“边的集合”((1,2),(2,3),(3,1),(1,4)))
- 扫描一遍点的集合(这里是(1,2,3,4)),如果都被标记了,那么就是连通图(对应“每个城市都有道路经过”);否则不是。
当计算机运行之后,我们开心的发现,得出了想要的结果。更开心的是它不仅可以对这几个城市查询道路,还可以对更多的城市做同样的查询!我们因此省去了自己人工查询的繁琐。
具体如何实现这个算法还要涉及更底层的方面,不过我想到这里数据结构与算法已经体现出来了——正是有了这兄弟俩,我们才能让借助计算机来得到想要的东西,从而大大方便我们的生活,以及创造出如此众多神奇的科技。
愈往深处和广处学习,愈觉得人类智慧的伟大。
数据结构与算法,正是前人在计算机领域智慧结晶的集中领域之一,我想有时甚至不需要知道学好它有什么用,因为体悟智慧本身不就是一种享受吗?
作者:猴鼻帕5
链接:https://zhidao.baidu.com/question/1951067610918494068.html
来源:百度知道
本人乃一个数据痴迷者,在计算机的道路上,也是一个数据结构的痴迷者,现在大学里面和同学搞开发也痴迷于数据库,我就我个人的理解给你谈一谈:
首先,数据结构是一门计算机语言学的基础学科,它不属于任何一门语言,其体现的是几乎所有标准语言的算法的思想。
上面的概念有一些模糊,我们现在来具体说一说,相信你们的数据结构使用的是一门具体的语言比如C/C++语言来说明,那是为了辅助的学习数据结构,而数据结构本身不属于任何语言(相信你把书上的程序敲到电脑里面是不能通过的吧,其只是描述了过程,要调试程序,还需要修改和增加一些东西)。
你们的书上开始应该在讲究数据的物理存储结构/逻辑存储结构等概念,说明数据结构首先就是“数据的结构”,在内存上的存储方式,就是物理的存储结构,在程序使用人员的思想上它是逻辑的,比如:
你们在C/C++中学习到链表,那么链表是什么一个概念,你们使用指针制向下一个结点的首地址,让他们串联起来,形成一个接一个的结点,就像显示生活中的火车一样。而这只是对于程序员的概念,但是在内存中存储的方式是怎样的那?对于你程序员来说这是“透明”的,其内部分配空间在那里,都是随机的,而内存中也没有一个又一根的线将他们串联起来,所以,这是一个物理与逻辑的概念,对于我们程序员只需要知道这些就可以了,而我们主要要研究的是“逻辑结构”。
我可以给你一个我自己总结的一个概念:所有的算法必须基于数据结构生存。也就是说,我们对于任何算法的编写,必须依赖一个已经存在的数据结构来对它进行操作,数据结构成为算法的操作对象,这也是为什么算法和数据结构两门分类不分家的概念,算法在没有数据结构的情况下,没有任何存在的意义;而数据结构没有算法就等于是一个尸体而没有灵魂。
估计这个对于算法的初学者可能有点晕,我们在具体的说一些东西吧:我们在数据结构中最简单的是什么:我个人把书籍中线性表更加细化一层(这里是为了便于理解在这样说的):
单个元素,比如:int i;这个i就是一个数据结构,它是一个什么样的数据结构,就是一个类型为int的变量,我们可以对它进行加法/减法/乘法/除法/自加等等一系列操作,当然对于单个元素我们对它的数据结构和算法的研究没有什么意义,因为它本来就是原子的,某些具体运算上可能算法存在比较小的差异;
而提升一个层次:就是我们的线性表(一般包含有:顺序表/链表)那么我们研究这样两种数据结构主要就是要研究它的什么东西那?一般我们主要研究他们以结构为单位(就是结点)的增加/删除/修改/检索(查询)四个操作(为什么有这样的操作,我在下面说到),我们一般把“增加/删除/修改”都把它称为更新,对于一个结点,若要进行更新一类的操作比如:删除,对于顺序表来说是使用下标访问方式,那么我们在删除了一个元素后需要将这个元素后的所有元素后的所有元素全部向前移动,这个时间是对于越长的顺序表,时间越长的,而对于链表,没有顺序的概念,其删除元素只需要将前一个结点的指针指向被删除点的下一个结点,将空间使用free()函数进行释放,还原给操作系统。当执行检索操作的时候,由于顺序表直接使用下标进行随机访问,而链表需要从头开始访问一一匹配才可以得到使用的元素,这个时间也是和链表的结点个数成正比的。
所以我们每一种数据结构对于不同的算法会产生不同的效果,各自没有绝对的好,也没有绝对的不好,他们都有自己的应用价值和方式;这样我们就可以在实际的项目开发中,对于内部的算法时间和空间以及项目所能提供的硬件能力进行综合评估,以让自己的算法能够更加好。
(在这里只提到了基于数据结构的一个方面就是:速度,其实算法的要素还应该包括:稳定性、健壮性、正确性、有穷性、可理解性、有输入和输出等等)
为什么要以结点方式进行这些乱七八糟的操作那?首先明确一个概念就是:对于过程化程序设计语言所提供的都是一些基础第一信息,比如一些关键字/保留字/运算符/分界符。
而我们需要用程序解决现实生活中的问题,比如我们要程序记录某公司人员的情况变化,那么人员这个数据类型,在程序设计语言中是没有的,那么我们需要对人员的内部信息定义(不可能完全,只是我们需要那些就定义那些),比如:年龄/性别/姓名/出生日期/民族/工作单位/职称/职务/工资状态等,那么就可以用一些C/C++语言描述了,如年龄我们就可以进行如下定义:
int age;/age变量,表示人员公司人员的年龄/
同理进行其他的定义,我们用结构体或类把他们封装成自定义数据类型或类的形式,这样用他们定义的就是一个人的对象的了,它内部包含了很多的模板数据了。
不知道你看完后,有没有新的收获?