为什么要了解数据结构和算法?
原文于:20190323
为什么要了解数据结构和算法——或者换一个问题:了解数据结构和算法意义是什么呢?
提出这样的问题,真想一板砖拍死对方,这叫什么问题啊!就好像问“吃饭有啥意义?为啥吃饭?不吃饭行吗?”,好吧,我承认算我自我找抽,
自己提出的问题,俗话不是说——自己约的 X,含着泪都要.....
如果我说没啥意义或者回答爱了解不了解,关自己何事。我想我也没有必要这么罗里吧嗦的写这篇东西了。
作为读者的您,可能就要扔鸡蛋了~~~。
当然如果真遇到这样的回答——那也没啥,就当不知道呗,多大点事儿。
当然提出这样问题的人,大致有这么几种:
* 纯粹好玩
* 满足一下好奇心
* 计算机或者编程从业者
* ...
第一种和第二种人,大概就是单纯的提出一个问题,并不需要深入思考的,可能就是为了问而问,也可能是有一点兴趣,但是也就是兴趣了解而已。
第三种人,大概对计算机知识有一定的了解,这个了解可能不单单是入门也有可能是已经入行很多年,但是突然扪心自问一下,发现自己还真答不上来!比如我。
其实我严重怀疑提出这样的问题,心里到底在想什么呢,这是有多无聊啊。
———————————————————————无耻的分割线—————————————————
言归正题,闲话少说。
先回答开篇的问题,先从其他方面说一下数据结构和算法,然后再回头想一下这个问题,可能你心里就明白了。那么我们就开始。
一般来说,去市面上买类似《数据结构和算法》这种书,书上提到的任何算法、数据结构,你都不会有机会重新实现一次。
因为,早有就各种各样的库,对外提供了工业级的、充分泛化的实现,只需拿来用就是了。
重写的话,你会面临如下的问题:
1)代码质量、执行速度,显然都极难超过经过千锤百炼的、在无数项目中经过充分测试的库实现;
2)书上都是为了教学而做的简化实现,实际使用中,需要对算法做一定的泛化。比如:
* C 的 qsort 库函数,只要保证数据是以指针数组索引的、对自定义数据须传入比较大小的功能函数,那么任何数据都可以用这个qsort算法排序;
* C++ 里面呢,则是和容器、迭代器之类东西结合和通盘考虑的,可泛用于任何符合规范的容器和原生数据类型。而课本上的实现,仅能支持数组中的整数。
想做到工业水平,没有足够的经验是不可能的;
* Java 和 C++ 也一样。
等等...
3)所有这些算法、数据结构的设计思路,会贯穿于绝大部分项目之中。
比如说,简单的冒泡算法,它是不是只是“多次扫描一个数组,交换遇到的每一对相邻的、顺序反了的数字;当不再发生交换时,数组已完成排序”,
更甚至于—— “丫的,老子好不容易才死记硬背下来的一段代码”啊!!!
如果你只学会了这个,那么,你真就完全白学了。那真是辛苦您、也受累了。
作为一个表现一般的排序算法,冒泡排序本身出场率就不高;何况还有各种提供了泛化的 sort 算法的库:如果仅仅记下了这个,说一句比较绝对的话
——那么你一辈子都不会遇到“必须重写冒泡算法”的场合。
但,如果你把冒泡算法记成:
就好像水中的气泡一样,每次只执行“相邻的元素比较密度(或其它特征),密度小的上浮,密度大的下沉”这个局部物理过程;多次进行后,局部有序
就会变成(相关特征上的)整体有序。
甚至:
模仿各种会导致整体有序现象的局部过程去处理数据,可以使得数据整体上满足类似的排布。
甚至:
考察任何自然规律,看它会产生什么有趣的后果——那么当需要达到类似的效果时,不妨尝试用程序模拟出这个规律,很可能就已经得到了想要的效果。
那,这一生,可就受用不尽了。
比如说,“高大上”的“神经网络”、“遗传算法”、“蚁群算法”等等等等,其实骨子里不都是这个“冒泡思路”吗?(这里我说的是思路,而非实现)
类似的,
各种树都是链表的“钩挂”思想 + 数组的“索引”思想的结合体;
“模拟退火算法”又是冒泡思路结出来的另一颗果子;
音频滤波算法就是简谐振动计算公式;
面向对象的“继承”不过是常见的“归一化”手法的另一个表述方式;
面向对象编程中常说的“ 23 种设计模式”也不过是“多态”思想的一种具体表现方式;
可以说,如果能像对冒泡算法的真正理解一样,彻底弄明白各种算法的设计思路并加以借鉴,那么你对这个世界的各种规律了解的有多透彻,
你的程序就可以写的有多灵动。
一旦掌握这个,从此,你再不必像那些菜鸟一样,绞尽脑汁敲出无数代码去“凑”需求;而是只需用代码编织出需要的规律,然后丢给CPU执行,
你真正想要的东西就会自然“涌现”:现在,你只要找出“结果已经出现”的识别方法,用它来结束你的逻辑就行了。
(当然,达成一个目的往往可以有多个不同的途径,不同途径利用不同的规律;那么哪个途径最优呢?算法课教过你:这就是所谓的“算法复杂度”)
——冒泡算法可不就是用代码编织了一个“数值大者靠前(或靠后)”的规律,然后丢给CPU一跑,一大片数据就有序了!
——遗传算法呢,不正是“抄袭”了自然界的自然选择规律吗?把这个规律丢给CPU一跑,居然连AI都弄出来了!
这些只是一些特别经典、特别著名的案例而已。
实际工作中,也是时刻都可能遇到一些新鲜的需求、场景;要完成工作,除了出苦力一行行码代码外,一样可以通过观察找到其中的规律,然后用代码编织规律,
再让这些规律去替你完成需求:后者往往会比前者简洁的多得多,执行速度一般也会快得多得多。
这类随时随地“发明”的算法实在不值一提,不能让你像那些著名案例一样一举成名;但它们却实实在在可以提高你的工作效率,让其他人望尘莫及。
——经常有高手骄傲的宣称,别人几万、几十万行代码都解决不了的问题,他数百行代码就清楚漂亮的解决了,执行效率还高出许多倍:他们就是这样做到的。
PS:这是一种夸张的描述,无非就是多了解一下一些高手写的代码以及应用场景。比如:JDK 源码、Spring 源码、Netty 源码 等等。
然后你就可以节省更多的时间去XXX,咳咳,别想多了,我的意思是接更多的需求,完成工作。升职加薪,走向...。
现在再回头看一下起初的问题——为什么要了解数据结构和算法?我想你心里可能就有答案了,虽然没有正面回答这个问题。但是我想表达的已经完成了。
同时我也在不断的学习和摸索中。
PS:我绝对不会说,我就是想让你们多干活,别让我每天都背后催你们今天的进度如何如何了~~~~23333
我这里也仅仅是个人的一些想法,不免带有个人的理解和偏见,甚至误区。请您自行斟酌。误入歧途,概不负责。
总结:
初级篇
1. 记住都有哪些算法,解决什么问题
2. 去试图解决实际的问题,自然会碰到之前算法解决的问题,使用这些算法
中级篇
1. 先完成初级篇
2. 记住算法的具体解决办法
3. 实际的问题如果有与标准算法相似但是不完全一样的,仔细分析差别,修改原有算法
高级篇
1. 先完成中级篇
2. 分析一下算法的解决办法是如何才能想到,最核心和最精妙的地方在哪儿
3. 实际的问题如果与标准算法都不太像,仔细想想这个问题的本质,借鉴经典算法精妙之处,自己设计自己要用的算法
骨灰篇
1. 先完成高级篇
2. 忘掉所有算法
3. 解决实际问题
记得给自己烧纸。。。
PS:
本文行文仓莽,如有不足之处,还请各位海涵斧正。
听说企鹅家又被挖断光纤了~~~~Orz....
浙公网安备 33010602011771号