程序员如何高效学好数据结构与算法?

简介:   主题:  1. 为什么要学数据结构  2. 数据结构学习秘籍  3. 算法为什么那么难  4. 算法学习秘籍  5. 如何打开数据结构与算法这两扇门  随着科学技术的发展,人工智能已渗透到各个行业,算法工程师非常火 爆,急缺大量人才,年薪也越来越高。刚毕业30-40万很常见。很多人想入手 学习算法,那么多算法,究竟该如何下手呢?  很多人看到招聘要求,算法工程师有很多具体分支:

  主题:

  1. 为什么要学数据结构

  2. 数据结构学习秘籍

  3. 算法为什么那么难

  4. 算法学习秘籍

  5. 如何打开数据结构与算法这两扇门

  随着科学技术的发展,人工智能已渗透到各个行业,算法工程师非常火 爆,急缺大量人才,年薪也越来越高。刚毕业30-40万很常见。很多人想入手 学习算法,那么多算法,究竟该如何下手呢?

  很多人看到招聘要求,算法工程师有很多具体分支:

  音/视频算法工程师 图像处理算法工程师 信号算法工程师 自然语言算法工程师 数据挖掘算法工程师 搜索算法工程师 例如有的招聘要求:

  1 ?至少熟悉一门编程语言C/C++/java/python/R

  2.熟练掌握数据结构,具有良好的算法基础和编程功底;

  /熟练运用各种常用算法和数据结构,有独立的实现能力;

  3 ?熟悉数据挖掘算法

  4 ?熟悉机器学习相关知识理论

  加分项:具有较为丰富的项目实践经验 那么是不是要直接学习这些算法呢?

  其实不然,万丈高楼平地起,任何高深的算法都要从基础算法学起,不可 能一口吃个胖子,所以入门算法还是要从基础开始:

  ?首先学习一门语言,例如C/C++/Java/python,初学者学C++比较普 遍。

  ?学数据结构,数据结构书有很多,但是有些教材晦涩难懂,建议看图 解多,通俗易懂的书,推荐《趣学数据结构》。

  ?学算法,不要直接看《算法导论》,大量证明会让你崩溃。推荐《趣 学算法》,有问题分析,完美图解,伪码详解,实战演练,适合初学 者快速掌握经典算法。

  1. 为什么要学数据结构?

  招聘搞笑事

  如果你关注招聘试题,越是大的公司,问的问题越基础,有的甚至问你什 么是栈和队列,反而一些小公司会关心你做过什么系统,关注点不同,大公司 更注重基础扎实,发展潜力,而小公司希望你立刻、马上为他干活,通常是没 什么技术含量的活。小公司喜欢细而长的竹子,大公司更喜欢碗口粗的竹笋。

  我曾经推荐一个学生到某知名公司,没多久,学生给我说了应聘的事情: “我介绍我开发了企业管理系统、在线商城系统等等,没想到他问我使用了什 么数据结构和算法,我懂很多技术,那么多功能我都实现了,他不问,却问我 使用了什么数据结构和算法,你说搞笑不?数据结构、算法我早就忘了,我会 开发软件还不行吗?”人力资源总监也反馈过来意见:“很搞笑,这个学生做 了不少系统,却说根本没用到数据结构和算法。”

  既然双方都觉得这是一个件搞笑事,我们就摊开来看,数据结构到底是什 么东西。

  拨云见日,看清数据结构

  遇到一个实际问题,需要解决两个事情:

  (1) 如何将数据存储在计算机中;

  (2) 用什么方法策略解决问题。

  前者是数据结构,后者是算法。只有数据结构没有算法,相当于只把数据 存储到计算机中而没有有效的方法去处理,就像一幢只有框架的烂尾楼;若只 有算法,没有数据结构,就像沙漠里的海市蜃楼,只不过是空中楼阁罢了。

  数据是一切能输入到计算机的信息总和,结构是指数据之间的关系,数据 结构就是将数据及其之间的关系有效地存储在计算机中。算法是指对特定问题 求解步骤的一种描述,说白了就是解决问题的方法策略。数据结构和算法不依 赖于语言,什么语言无所谓。但是如果上机实现的话,就要使用计算机语言。

  遇到一个实际问题,充分利用所学的数据结构,将数据及其之间的关系有 效地存储在计算机中,然后选择合适的算法策略,并用程序高效实现,这就是 N.Wirth教授所说的:数据结构+算法=程序。

  为什么要学习数据结构?

  计算机专业本科生都开设数据结构课程,它是计算机学科知识结构的核心 和技术体系的基石。研究生考试也是必考科目,随着科学技术的飞速发展,数

  据结构的基础性地位不仅没有动摇,反而由于近年来算法工程师的高薪火爆, 而得到了业内空前的重视。很多人觉得基本的数据结构及操作己经在高级语言 (如C++、JAVA语言中)中封装,栈、队列、排序、优先队列等都可以直接 调用库函数,学会怎么调用就好了,干嘛要重复造轮子?那么到底有没有必要 好好学习数据结构?

  先看学习数据结构有什么用处:

  (1) 学习数据有效存储的方法

  很多学生在学习数据结构时,问我要不要把单链表插入删除代码背下来?

  要不合上书就不会写了。我非常诧异,为什么要背?理工科技术知识很少需要 记忆的,是用的,用的!学习知识不是死记硬背,更重要的是学习处理问题的 方法。同一个问题,如何有效地存储数据,不同的数据结构产生什么样的算法 复杂性,有没有更好的存储方法提高算法的效率?例如,用顺序表查找需要 〇(?)的时间复杂度,用平衡树查找需要〇(l〇g?)的时间复杂度。这是什么概念 呢?就像你有10个亿,一觉醒来,兜里只剩下30块!

  (2) 处理具有复杂关系的数据

  现实中很多具有复杂关系的数据,无法通过简单的库函数调用实现。专业 认证中特别强调培养学生解决复杂工程问题的能力,什么是复杂工程问题?就 是需要综合运用多个知识技术解决的问题。如同现在很多芯片高度集成,完全 不需要芯片内部如何,直接使用就行了。但是,如果在现实中遇到一个复杂问 题,一个芯片只能完成其中一个功能,难道要连接十几块芯片来解决这一个问 题?你在搞圣诞树嘛? 一个树枝挂个小礼物,叮叮当当的乱响。这显然是不合 适的,我们需要的是完成该复杂问题的一个芯片,因此需要运用所学的数据结 构知识,高效处理具有复杂关系的数据。

  通过学习数据结构,更加准确、深刻地理解不同数据结构之间的共性和联 系,学会选择和改进数据结构,高效地设计并实现各种算法,这才是数据结构 的精髓。

  2. 数据结构学习秘籍

  数据结构为什么那么难?

  网络上太多的同学吐槽被虐,如滔滔江水连绵不绝,数据结构太难了!真 的很难吗?其实数据结构只是讲了三种:线性结构、树、图。到底难在哪里 呢?通过调查了解大概有四个原因:

  (1)无法接受的描述方式

  数据结构的描述大多是抽象的形式,我们使用自然语言表达习惯了,不容 易接受数据结构的抽象表示。不止一个学生问我,书上的“ElemType”到底是 什么类型?运行时怎么提示错误。它的意思就是“元素类型”,只是这样的描 述,你需要什么类型就写什么类型,例如int。这样的表达方式让不少人崩溃。

  (2) 不知道什么用处

  尽管很多人学习数据结构,有的人是应付考试,有的人考研需要,有的人 参加算法竞赛需要,而很多人不太清楚学习数据结构有什么用处,迷迷糊糊看 书、做题、考试。

  (3) 体会不到其中的妙处

  由于教材、教师等等各种因素影响,很多学生没有体会到数据结构处理数 据的妙处,经常为学不会而焦头烂额,无法体会其中乐趣,有趣是才有意思, 兴趣是最大的驱动力。一旦体会到其中的奥妙,就会有停不下来的感觉。有读 者给我留言,老师看了你的书根本停不下来。其实,我写书的时候也停不下 来,神同步。

  (4) 语言基础不好

  我一直强调先看图解,理清思路,再上机。还是有很多同学己经理解了思 路后,因为缺少main函数,输入输出格式不对,缺少括号等等各种语言问题卡 壳,而这一切统统戴给了“数据结构太难了”这个大帽子。

  数据结构学习秘籍

  在讲学习秘籍之前,首先了解一下数据结构学习的三种境界:

  (1) 会数据结构的基本操作

  这是最基础的要求,学会各种数据结构的基本操作,取值、查找、插入、 删除等。先看图解,理解各种数据结构的定义,操作方法,然后看代码,尝试 自己动手上机运行,逐渐掌握基本操作。初学时,要想理解数据结构,一定要 学会画图,通过画图形象表达,更能体会其中的数据结构关系。因此,初学阶 段学习利器:画图,理解,画图。

  (2) 会利用数据结构,解决实际问题

  在掌握了书上的基本操作之后,就可以尝试利用数据结构解决一些实际问 题了,先学经典应用问题的解决方法,体会数据结构的使用方法,然后再做 题,独立设计数据结构解决问题。要想熟练应用就必须做大量的题,从做题中 体会其中的方法。最好进行专项练习,比如线性表问题,二叉树问题,图问 题,该阶段学习利器:做题,反思,做题。

  (3) 熟练使用和改进数据结构,优化算法

  这是最高境界了,也是学习数据结构的精髓所在,单独学习数据结构是无 法达到这种境界的。它需要在学习算法的过程中慢慢修炼。在学习算法的同 时,逐步熟练应用、改进,慢慢体会不同数据结构和算法策略的算法复杂性, 最终学会利用数据结构改进和优化算法。该阶段已经在数据结构之上,通过在 测试系统上刷各种算法题,体会利用数据结构改进优化算法。该阶段学习利 器:刷题,总结,刷题。

  刷题网站:打比赛 HDU、POJ、Vjudge、Code Forces,找工作 LeetCode

  3. 算法为什么那么难

  很多人感叹:算法为什么那么难!

  首先,算法本身具有一定的复杂性,还有一个原因:讲的太烂!

  算法的教与学有两个困难:

  (1) 我们学习了那些经典的算法,在惊叹它们奇思妙想的同时,难免疑虑 重重:这么牛,怎么想到的?对学生来说,这可能是最费解、也最让人窝火的 地方。高手讲,学算法要学它的来龙去脉,包括种种证明。但这对菜鸟来说,

  简直比登天还难,很可能花费很多时间也无法搞清楚。这条路对大多数人来

  说,是行不通的,那怎么办呢?下功夫去记忆书上的算法?记住这些算法的效 率?看似学会了,其实两手空空。遇到一个新问题,仍然无从下手。可这偏偏 又是极重要的,无论作研究还是实际工作,一个计算机专业人士最重要的能 力,就是解决问题一解决那些不断从实际应用中冒出来的新问题。

  (2) 算法作为一门学问,有两条几乎平行的线索。一个是数据结构(数据 对象):数、矩阵、集合、串、排列、图、表达式、分布等等。另一个是算法策 略:贪心、分治、动态规划、线性规划、搜索等等。这两条线索是相互独立 的:同一个数据对象(例如图)上有不同的问题,例如单源最短路径和最优二 叉树,就可以用到不同的算法策略,如贪心和动态规划;而同一个算法策略, 例如排序和整数乘法,也会用到不同的数据结构。它们之间是多对多的关系。

  两条线索交织在一起,该如何表述?

  我们早己习惯《数据结构》中讲数据结构,《算法设计与分析》里面讲算 法策略。各说各的,讲算法设计时就假设你己经对数据结构了如指掌,还没有 哪一本算法书很好的解决这两个困难,传统的算法书,大多注重内容的收录, 但却忽视思维过程的展示,因此我们学习了经典的算法,却费解于算法设计的 过程。遇到一个实际问题,通过问题分析,选择使用什么样的算法策略,基于 这种二手卖号平台算法策略选择什么样的数据结构,有时算法策略和数据结构的选择并不是 唯一的,不同的算法策略和数据结构设计的算法,其复杂性是不同的。而很多 书就是灌输式的讲一个实例,一下子就选择了一个认定是最优的算法策略,告 诉你就这样干,不谈数据结构,然后分析算法复杂性,就结束了。原则上讲算 法策略就讲算法策略,不依赖任何程序设计语言和数据结构,但对很多学生来 讲,尤其是语言没学好,数据结构也不熟练的同学,只讲算法策略,如同空中 楼阁。自己用算法解决实际问题,一头雾水。

  《趣学算法》,从问题出发,根据实际问题进行分析,选择合适的算法策 略,并分析为什么采用这种算法策略,然后选择什么数据结构,不同的数据结 构复杂性会有什么区别,巧妙地将数据结构和算法策略拧成了一条线。通过大 量实例,充分展现算法设计的思维过程,让学生充分体会遇到一个问题,如何

  分析,使用什么算法策略,采用什么数据结构,算法的复杂性如何?是否有优 化的可能?

  西方教育旨在激发学生对世界的好奇心,而在这里,我们培养的是让学生 怀着一颗好奇心,思考问题、解决问题的能力。更重要的是一一体会学习的乐 趣,发现算法的美!

  4. 算法学习秘籍

  知识在于积累,学习需要耐力。学习就像挖金矿,或许一开始毫无头绪, 一头雾水,但转个角度,换换工具,时间久了总会找到一个缝隙。成功就是你 比别人多走了一段路,或许恰恰是那么一小步。

  第一个建议:多角度,对比学习

  学习算法,可以先阅读一本简单的入门书,然后综合几本书横向多角度 看,例如学习动态规划,拿几本算法书,把动态规划这章找出来,比较学习, 多角度对比分析更清晰,或许你会恍然大悟,噢,原来如此简单。或许有同学 说我哪有那么多钱买那么多书,只要你想学习,没有什么可以阻挡!你可以图 书馆借,也可以联系你的老师,每学期上课前,我都会告诉学生,如果你想学 习却没钱买书,我可以提供帮助。想一想,你真的没有办法?

  第二个建议:大视野,不求甚解

  经常有学生为了一个公式推导,或几句代码抛锚,甚至停滞数日,然后淹 没在无尽的挫败感中,把自己弄得垂头丧气。公式可以不懂,代码可以不会。 你不必投入大量精力试图推导书上的每一个公式,也不必探究语法或技术细 节。学算法就是学算法本身,首先是算法思想,解题思路,然后是算法实现, 算法思想的背后可能有高深的数学模型,复杂的公式推导,你理解了当然玄 妙,不懂就拉倒。算法实现可以用任何语言,所以不必纠结是C,C++,Java, Python,更不必管严格的语法规则,除非你要上机调试。建议还是先领会算 法,写伪代码,在大脑中调试吧,如果没有良好的编程经验,一开始就上机或 许更让你崩溃。遇到不懂的部分,浏览一下或跳过去,读完了还不明白再翻翻 别的书,总有一天,你会发现,“暮然回首,那人却在灯火阑珊处”。

  第三个建议:多交流,见贤思齐

  与同学,朋友,教师或其他编程爱好者们一起学习和讨论问题,是取得进 步最有效的办法,也是分享知识和快乐的途径。加入论坛,加入交流群,会了 解其它人在做什么,怎么做,遇到问题可以请教高手,带来醍醐灌顶的喜悦; 也可以应助菜鸟,使你暗自得意,信心倍增。论坛和群也会分享大量的学习资 料和视频,还有不定期的培训讲座,读书交流会,你会发现,不是你一个人在 战斗!

  第四个建议:勤实战,越挫越勇

  实践是检验一切真理的标准。古人云:“学以致用”,“师夷长技以制 夷”。请不要急切期盼“实际的”例子,更不要看不起小实例,“不积跬步, 无以至千里”。大规模的成功商业案例所采用的算法,人工情感,无人驾驶, 不是我们目前要解决的问题。看清楚脚下的路,比仰望天空更实际,多做一些 实战练习,更好地体会算法的本质,在错误中不断成长,越挫越勇,终究会成 参天大树。

  第五个建议:看电影,洞察未来

  不管是讲《人工智能》,还是《算法分析》,我都会建议同学们去看一看 科幻电影,如《人工智能》、《记忆裂痕》、《绝密飞行》、《未来战士》、 《她》等等。奇妙的是,这些科幻的东西,正在一步步的实现,靠的是什么? 人工智能。计算机的终极是人工智能,人工智能的核心

目录
相关文章
|
7月前
|
算法 搜索推荐 Java
「程序员必须掌握的算法」字典树「上篇」
「程序员必须掌握的算法」字典树「上篇」
|
3月前
|
机器学习/深度学习 存储 算法
【程序员必须掌握的算法】【Matlab智能算法】GRNN神经网络-遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值
【程序员必须掌握的算法】【Matlab智能算法】GRNN神经网络-遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值
|
3月前
|
机器学习/深度学习 搜索推荐 算法
程序员必须掌握的排序算法:插入排序的原理与实现
程序员必须掌握的排序算法:插入排序的原理与实现
30 1
|
4月前
|
算法 搜索推荐 Java
「程序员必须掌握的算法」字典树「上篇」
「程序员必须掌握的算法」字典树「上篇」
|
4月前
|
机器学习/深度学习 算法 Java
「程序员必须掌握的算法」动态规划「中篇」
「程序员必须掌握的算法」动态规划「中篇」
|
4月前
|
算法 程序员
「程序员必须掌握的算法」双指针「上篇」
「程序员必须掌握的算法」双指针「上篇」
|
4月前
|
人工智能 算法 程序员
「程序员必须掌握的算法」动态规划「上篇」
「程序员必须掌握的算法」动态规划「上篇」
|
4月前
|
算法 Java 程序员
【Java程序员面试专栏 数据结构篇】五 高频面试算法题:二叉树
【Java程序员面试专栏 数据结构篇】五 高频面试算法题:二叉树
36 0
|
4月前
|
算法 Java 程序员
【Java程序员面试专栏 数据结构篇】二 高频面试算法题:链表
【Java程序员面试专栏 数据结构篇】二 高频面试算法题:链表
135 0
|
4月前
|
搜索推荐 算法 Java
快速排序算法,这么写打败95%的程序员
1960年,英国计算机科学家霍尔提出了一种高效的排序算法——快速排序。其核心思想是选定一个基准元素,将需排序的数组分割成两部分。其中一部分都比基准元素小,另一部分都比基准元素大。接着对这两部分分别进行快速排序,最后通过递归完成整个排序过程。这种算法效率高,被广泛应用。