关于算法学习的总结和感悟(原创)

原创 2012年03月26日 22:43:43


时隔一年重读《算法导论》,去年读到了二叉查找树就搁浅了,今年从头捡起,希望能走的
更远一些。算上大学时的数据结构与算法课,今年可以算是第三波学习攻势了。随着学习的深入,
对算法的学习渐渐有了些自己的看法和感悟。


一.为什么学习算法?

记得初学算法时不明白为什么费力分析程序的执行步骤后,还要用公式表达出来并求极值。
一遍遍的学习渐渐有了领悟:算法研究是用来做大事的!之所以分析效率还求极限,是因为
各种算法和数据结构都要研究其在海量输入数据或最坏最不利的情况下的效率表现。如果
只是我们每天乏味工作中那三两个数的排序,几十个数值对的哈希,那其实怎样实现都无所
谓了。

所以个人觉得,学习算法能提高分析代码、洞察效率的能力,并且它也是我们继续深入学习
操作系统、网络编程、数据库的基础。如操作系统管理内存的红黑树,保存进程优先级的
最大堆,程序运行时函数调用的栈结构,数据库中的B树索引,大量数据的外部多路归并排序
和编译器将表达式解析为树然后遍历等等。所以要想深入计算机科学的内核,算法这一关是
必须过的,这也是我的学习计划。

PS:关于我的学习计划:http://blog.csdn.net/dc_726/article/details/7017781。可以看到算法
是在整个知识体系的最底层部分,这是我宏伟蓝图的基础,呵呵~

如果你学了感觉它没用,其实不是那样的,只是你还没碰到需要它的场合,杀鸡焉用牛刀,
记住它是用来做大事情!


二.算法的学习方法

学习算法如果选择好方法学到最后很可能就什么都不记得了,就像我第一次读《算法导论》时
一样,也仔仔细细的看了,还做了些习题,可读完过后感觉什么都没掌握一样。这次重读,我
找到了适合自己的方法:

1.《算法导论》中几乎每个数据结构与算法都会有对应的例子和图示用来生动讲解。光看一遍
还不够,拿起笔跟着例子走一遍算法的伪代码,看看算法每一步中的值、状态是怎么变化的。
这样才能把例子搞透,不然白瞎了《算法导论》里一幅幅那么清楚明了的图示了。

2.搞懂例子,自然就要实现算法了。不管算法多么简单,一定要自己动手实现,切忌手懒啊。
实现好一个个算法的代码都保存备份好,这也是一笔财富,而且很有成就感。 关于具体用什么
语言来实现稍后再说。

3.只是搞清楚了基本的算法还不够,《算法导论》每节后还有不少有价值的习题,特别是每章
最后都有一些思考题,其中有的是数据结构进行扩展的,有的是算法的实际应用,一定要好好
研究才能更深的理解这一节的知识。
例如堆思想的应用:http://blog.csdn.net/dc_726/article/details/7285040
例如二叉树的变种:http://blog.csdn.net/dc_726/article/details/7391988

4.最后一定要记笔记,不管是手写的还是博客。笔记不仅方便以后的查找,记笔记的过程也会
激发你大脑思考,很多奇思妙想都是动笔头时冒出来的。
有关笔记及一些记录工具:http://blog.csdn.net/dc_726/article/details/7068357
记住:学习并不浪费时间,浪费时间的是重复学习


三.实现语言的选择

大学时的数据结构课要求使用的是C++,后来我第一遍学《算法导论》时用的是我最习惯的
Java,而现在第二遍学习时我用的却是C。不用我最熟悉的Java而用C的原因是C语言的简洁
和指针的强大,这一点在实现复杂一些的数据结构时体现的尤为突出。并且很多底层的东西
如操作系统、编译器等也都是C的地盘,因此同时学习C语言和算法对未来的深入学习有着
极为重要的作用。暂时放下我的老朋友Java,拥抱C!


四.要把握本质

初学算法时,搞不清楚为什么有那么多的数据结构,那么多的排序算法。散列表不是已经很好
了吗,为什么又搞出一堆二叉树?快排不是已经很完美了吗,为什么还有堆排、冒泡、合并排?
一遍遍地学习,学会比较各种数据结构和算法后,才能看清这些的设计背后的本质。

1.各种排序

快速排序的确很完美了,但其他排序方法也是有他们的用武之地的。对于输入数据范围已知时,
如输入数据都是0到10之间的整数,那么计数排序就可以上场了。又如当输入数据是海量的,
没法一次全部拿到内存中排好时,可以将输入数据分成多块,每块拿到内存中排序,之后对每
个排好序的块进行多路归并。

快速排序:http://blog.csdn.net/dc_726/article/details/7292361
多路归并:http://blog.csdn.net/dc_726/article/details/7262665

2.堆、栈及链表

堆、栈、链表都是再简单不过的数据结构了,但我们学习时不能就局限于对简单应用的掌握,
这些简单结构在特定场景或与其他数据结构结合起来使用时会产生巨大的威力。如堆在K路
归并中与其他内排序的配合,用栈来实现递归调用(如二叉树的非递归中序遍历)等。
二叉树遍历:http://blog.csdn.net/dc_726/article/details/7391288

3.哈希与红黑

散列表性能很好,可是当需要随时动态插入数据时,随着数据越来越多,散列表中的冲突数据
也越来越多,这样的静态散列自然要性能下降。可是红黑树却可以保证树的高度从而保证效率,
所以尽管红黑树很复杂,但它却是维护动态集合的不错选择。然而散列表也是与时俱进的,
动态哈希能够在散列表中数据增多到一定量时自动增大散列表,并重新哈希。这就需要较大的
存储空间,但现今的内存白菜价,所以散列表也可以维护动态数据集合了,所以memcached火
起来了。

4.树家族

平衡树家族很庞大,有AVL树、红黑树、Treap树以及大小平衡树(SBT)。但学习时要把握住
他们的本质:他们都是平衡二叉树,区别只是在如何保持树的高度不会过高上。为何关注树的
高度?因为平衡二叉树上各种操作的性能都是由树高来决定的。

此外常见的还有基数树和Trie树。在树结点中保存01或者各种字符,用于排序01串以及文本统计。
Trie树的应用:http://blog.csdn.net/dc_726/article/details/7163466


五.算法的等级修炼 

我心中对算法有个模糊的分级,学习时可以设定自己短期或长期想要达到的目标。
现在快要第二次学完《算法导论》基础部分的十四章了,也只是了解的程度,才刚刚开始有些
感悟。都说算法是内功,学习起来需要旷日持久、小火慢熬,所以还要努力啊!

1.了解:了解各种算法和数据结构的基础知识,但对他们的具体应用范围一头雾水。

2.掌握:能够清楚明白各种算法的优劣,并开始学会比较他们的应用场景。

3.选择:至此各种结构与算法已经在我们的锦囊里了,碰到问题时要学会从中拿出合适的。

4.扩展:根据具体问题对现有算法进行简单的扩展和改造,并进行效率分析。

5.设计:能为现实生活中复杂的问题设计全新的数据结构或算法来解决。


结束语

算法是美妙而迷人的,但越深入就需要越强的数学功底。每个人可以根据自己的兴趣浓淡、
个人能力为自己制定目标。我自知自己没有那么强的能力,所以个人制定目标等级是3和4
之间,也就是能够应用这些现有的数据结构和算法,能简单的扩展和分析就可以了。希望
大家也都能为自己制定合适的目标,重要的是享受算法的学习过程。切忌走火入魔啊,哈哈!


版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问 http://blog.csdn.net/dc_726 举报

相关文章推荐

数据结构与算法学习心得

数据结构与算法的内容还有很多。但是由于时间的关系,我并没有深入下去,尤其是查找时用到的平衡二叉树、B_和B+树,还有红黑树等等。希望以后有时间可以继续看。 首先,简要回顾一下学习的内容。简单的说,是...

《C程序设计语言》第四章 函数和程序结构

4.1 函数的基本知识 如果函数定义中省略了返回值类型,则默认为int类型。 练习4-1     编写函数strindex(s, t),它返回字符串t在s中最右边出现的位置。 如...
  • dc_726
  • dc_726
  • 2011-12-15 21:09
  • 3167

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

结构体位域在内存中的分布与平台大小端的关系

powerpc平台是大端的,x86是小端的,两者之间应用层开发有所不同,结构体位域在通讯协议打包解包中会用到很多,两种不同的平台之间通讯的时候,如何使两者匹配,这是个问题,本人深入研究了这个问题,看了...

TI笔试总结

问:嵌入式系统中的两种处理方式? 中断和s

链表逆置

这也是面试时常考的问题: pNode reverseList(pNode head) { pNode p1; pNode p2; pNode p3; //如果为空或者只有一个元素,直接返回 ...

招聘季总结

其实在大三的时候就决定读研究生了,但也不想错过招聘季的笔试面试,所以想试试各个公司的招聘,为以后积累点经验。 1.华为是最早去试的公司,在大四前的暑假,上研所要招实习生,当时准备了简历就报名了。首先是...

操作系统内核Hack:(二)底层编程基础

操作系统内核Hack:(二)底层编程基础在《操作系统内核Hack:(一)实验环境搭建》中,我们看到了一个迷你操作系统引导程序。尽管只有不到二十行,然而要完全看懂还是需要不少底层软硬件知识的。本文的目的...
  • dc_726
  • dc_726
  • 2015-10-09 21:22
  • 4327

程序员的八重境界

看到一篇有趣的文章The Eight Levels of Programmers。以前似乎看过不少这种程序员的多少个级别、境界,但这篇语言很风趣,而且分类比较细化,让人觉得挺合情合理、无法反驳的。绝大...
  • dc_726
  • dc_726
  • 2017-08-31 04:58
  • 22361

编程之美:判断两链表是否相交

《编程之美》里面有一篇是讲如何判断两链表是否相交,读后觉得原文太过啰嗦。于是,笔者总结了一下,此类问题可以扩展为两大类,分别是:1、单链表与环问题http://blog.csdn.net/liuxia...

C++学习笔记

1. //将字符串s全变为大写 for(char &i : s) { i = toupper(i); } 范围for语句是C++11标准,用g++编译时,需要加上-std=c++11,...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)