算法和结构化数据初识及学习之路

--  算法就是能利用特定方法使得现实问题更加简便的去解决的方法。同一问题的解决,可以有不同的算法完成,算法本身可简便,也可复杂。算法在大部分程序中有着举足轻重的作用。数据结构用来存储实际业务的运算结果,算法用来解决实际应用场景的数据处理过程,实际上编码的本质就是数据结构和算法的搭配。
  在做视频的算法时,肯定免不了视频的解码,拿到一幅图像,甚至到了拿到一个像素,才是开始算法本身的工作。而这些工作,对于专注于某个算法的人来说,应该是透明的。而且我相信能独立的编写出从读取视频到获取像素的全部程序的人也不是很多。
  matlab提供了强大的函数库,使得复杂的数学运算(尤其是矩阵运算(奇异值分解、插值等等))、图像处理、模式识别等基本算法能够通过函数调用来完成,使得自己能够专注于问题,提出改进的思路。而且对于图像、视频,提供的读写函数自动完成了编解码操作,让我们可以专注于算法本身。但是缺点就是速度慢,对于实时性验证的场合不太适合。也有很多用C写算法的。算法无非就是一个解决问题的办法,输入、输出,使用函数来描述刚刚好。而且,一般对于算法的描述,也是按步骤进行的,与面向过程的思想是相符的。加上C语言较高的执行效率,的确是一种不错的选择。而且,现在有很多库也可以供大家使用,能让程序员专注于解决问题。但是,算法本身也有一些特点,比如参数很多,导致函数的声明非常长。有时我不得不将一些参数、数据结构设为全局变量,要不然难以完成递归的操作。而全局变量使用太多也不是什么好事。
  算法本质上是基于过程的、有具体步骤的,所以我不太倾向于在具体的算法之间使用继承派生关系,更多的时候,只是将算法与算法所操作的数据进行封装,这更像是一种基于对象的思路(带类的C语言)。而泛型编程在算法中的使用可能也不是很广泛吧,特定算法要处理的数据类型往往是确定的,不太可能出现“泛型”问题。

-- 正在准备看的数据结构和算法书:《算法设计手册》《微软的梦工厂》《大话数据结构》.
我的算法学习之路:http://www.cnblogs.com/figure9/archive/2014/05/05/3708351.html
算法工程师学习之路- https://blog.csdn.net/anthea_luo/article/details/78767894
算法工程师面试常见问题- https://blog.csdn.net/gzj_1101/article/details/79514902
关于算法,那些你不知道的事-https://blog.csdn.net/dc_726/article/details/51724097

-- 那到底什么样的才算是授人以渔的呢?波利亚的《如何解题》绝对算是一本,他的《数学的发现》也值得一看。具体到算法书,那就不是光看text book就足够的了,为了深入理解一个算法的来龙去脉前因后果,从一个算法中领悟尽量深刻的东西,则需要做到三件事情:
  1. 寻找该算法的原始出处:TAOCP作为一个资料库是绝对优秀的,基础的算法只要你能想到的,几乎都可以在上面找到原始出处。查到原始出处之后(譬如一篇paper),就可以去网上搜来看了。因为最初的作者往往对一个方案的诞生过程最为了解。比如经典数据结构中的红黑树是出了名的令人费解的结构之一,但它的作者Sedgewick一张PPT(http://groups.google.com/group/pongba/browse_thread/thread/3513a21065faba68),给你讲得通通透透,比算法导论上的讲法强上数倍。
  2. 原始的出处其实也未必就都推心置腹地和你讲得那么到位:前面说过,算法设计出来了之后人们几乎是不会去回顾整个的思维过程细节的,只把直指目标的那些东西写出来。结果就又是一篇欧几里德式的文章了。于是你就迷失在一大堆“定义”、“引理”、“定理”之中了。这种文章看上去整个写得井井有条,其实是把发明的过程整个给颠倒过来了,我一直就想,如果作者们能够将整个的思路过程写出来,哪怕文字多上十倍,我也绝对会比看那一堆定义定理要容易理解得多。话说回来,怎么办?可以再去网上找找,牛人讲得未必比经典教材上的差(https://blog.csdn.net/g9yuayon/article/details/2574781)。那倘若实在找不出好的介绍呢,就只能自己揣摩了。揣摩的重要性,是怎么说都不为过的。揣摩的一些指导性的问题有:为什么要这样(为什么这是好的)?为什么不是那样(有其它做法吗?有更好的做法吗?)?这样做是最好的吗?(为什么?能证明吗?)这个做法跟其它的什么做法有本质联系吗?这个跟这个的区别是什么?问题的本质是什么?这个做法的本质又是什么?到底本质上是什么东西导致了这个做法如此..?与这个问题类似的还有其它问题吗?(同样或类似的做法也适用吗?)等等。
 3. 不仅学习别人的思路,整理自己的思路也是极其重要的:详见《跟波利亚学解题》(https://blog.csdn.net/pongba/article/details/2302905)的“4. 一个好习惯”和“7. 总结的意义”。

--  这里说的算法,并不是计算机系本科课程《算法与数据结构》里那个算法。那门课里讲的,是排序、查找这类“确定性算法”;而这里我们说的,是用统计方法对数据进行建模的“概率性算法”。
 而算法工程师的真正价值,就是洞察问题的数据先验特点,把他们表达在模型中,而这个,就需要下一个层次的能力了。
 一个团队的定海神针,就是能把问题转化成目标函数的那个人——哪怕他连开源工具都不会用。100 万找到这样的人,可真是捡了个大便宜。
 在机器学习领域,算法工程师脚下的进阶之路是清晰的:当你掌握了工具、会改造模型,进而可以驾驭新问题的建模,就能成长为最优秀的人才。

> 数据结构定义:
我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(如元素的CURD、排序等)而执行的相应操作,这个相应的操作也叫算法。
 数据结构 = 元素 + 元素的关系 ;

 算法 = 对数据结构的操作;
 算法:算法就是:解决问题的方法和步骤;
  如计算机内存中栈和堆的区别,不懂数据结构的人可能会认为内存就是分两大部分,一块叫栈,一块叫堆,显然这是非常肤浅且不正确的结论。
  实际上如果一块内存是以压栈出栈的方式分配的内存,那么这块内存就叫栈内存,如果是以堆排序的方式分配的内存,那么这块内存就叫堆内存,其最根本的区别还是其内存分配算法的不同。
  例如,函数的调用方式也是通过压栈出栈的方式来调用的,或者操作系统中多线程操作有队列的概念,队列用于保证多线程的操作顺序,这也是数据结构里面的内容、或者计算机编译原理里面有语法树的概念,这实际上就是数据结构里面的树,比如软件工程、数据库之类都有数据结构的影子。

-- 在计算机系统中,CPU 可以直接操作内存,关于 CPU 对内存的操作与控制原理可以简单理解如下:
地址线 : 确定操作哪个地址单元 
控制线 : 控制该数据单元的读写属性 
数据线 : 传输 CPU 和内存之间的数据
  什么叫结构体:结构体是用户根据实际需要,自己定义的复合数据类型
  指针: 
  指针就是地址,地址就是指针。 
  指针变量是存放内存单元地址的变量,它内部保存的值是对应的地址,地址就是内存单元的编号(如内存地址值:0xffc0)。 
  指针的本质是一个操作受限的非负整数 

-- 引用Quora上的回答:

  I see it time and again in Google interviews or new-grad hires: The way data structures and algorithms—among the most important subjects in a proper computer science curriculum—are learnt is often insufficient. That's not to say students read the wrong books (see my recommendation below) or professors teach the wrong material, but how students ultimately come to understand the subject is lacking.(我多次在google面试或者毕业招聘的时候看到这样的情形:学习数据结构和算法--CS课程里面几乎最重要的课程--的方式很不科学!!到不是说大家用的书或者老师用的材料不对,而是说学生们对于这些课程本身的理解非常缺乏.)

 

  The key to a solid foundation in data structures and algorithms is not an exhaustive survey of every conceivable data structure and its subforms, with memorization of each's Big-O value and amortized cost. Such knowledge is great and impressive if you've got it, but you will rarely need it. For better or worse, your career will likely never require you to implement a red-black tree node removal algorithm. But you ought be able—with complete ease!—to identify when a binary search tree is a useful solution to a problem, because you will often need that skill.(
打好数据结构和算法基础的关键并不在于对于所有数据结构的细致的了解,不是记住每一个大O值或者摊余成本..((@_@;)? [不懂]).
如果这些知识你都掌握了,当然很棒并且可以给人留下很深的印象,但是你基本上用不着啊!
你的职业生涯中或许永远都不会要求你实现一个红黑树删除节点的算法.但是!你必须有能力而且手起刀落轻轻松松的识别出什么时候使用二叉树更简单更有效, 因为你十分需要这样的技巧.)

  So stop trying to memorize everything. Instead, start with the basics and learn to do two things:
Visualize the data structure. Intuitively understand what the data structurelooks like, what it feels like to use it, and how it is structured both in the abstract and physically in your computer's memory. This is the single most important thing you can do, and it is useful from the simplest queues and stacks up through the most complicated self-balancing tree. Draw it, visualize it in your head, whatever you need to do: Understand the structure intuitively.
Learn when and how to use different data structures and their algorithms in your own code. This is harder as a student, as the problem assignments you'll work through just won't impart this knowledge. That's fine. Realize you won't master data structures until you are working on a real-world problem and discover that a hash is the solution to your performance woes. But even as a student you should focus on learning not the minutia details but the practicalities: When do you want a hash? When do you want a tree? When is a min-heap the right solution?
(所以,不要试图记住所有的东西.而是从基础开始,做两件事:
第一件事. 把数据结构图形化,视觉化.(突然想起来我高中竞赛老师说的一句话:数形结合千般好,一旦不做万事休啊! 就是要画图! )在直觉上感受一个数据结构是什么样子的.使用它是什么感觉,抽象上和具体实现上是什么样子的.这就是最重要的事情.并且无论是对于简单的队列,栈还是天杀的平衡树都很重要而且有效.把数据结构画出来,在你的脑袋瓜里面就能想象出来,总之,你需要做的就是,直观的去了解这些数据结构.
第二件事.学习什么时候用什么样的数据结构和算法.对于学生来说这很难,而且你要做作业的时候老师也没告诉你们这该怎么办.╮( ̄▽ ̄")╭ 不过没关系. 你要认识到当你真正处理到现实问题的时候或许你才能掌握某些数据结构,比如哈希表.但是即使是个学生,你也应该知道数据结构的实用性:什么时候你需要个哈希表,什么时候你需要个树,什么时候你需要个堆? 而不是一开始就陷入到追求细节中去.)

  One of the questions I ask in Google engineering interviews has a binary search tree as a potential solution (among others). Good candidates can arrive at the binary search tree as the right path in a few minutes, and then take 10-15 minutes working through the rest of the problem and the other roadblocks I toss out. But occasionally I get a candidate who intuitively understands trees and can visualize the problem I'm presenting. They might stumble on the exact algorithmic complexity of some operation, but they can respond to roadblocks without pause because they can visualize the tree. They get it.
(我在google面试的时候,我经常会问一个可以由二叉树搜索解决的问题. 好的应聘者可以几分钟内就可以想到用二叉树来解决,而且对于我的其他问题也差不多10-15分钟就可以解决.当然,偶尔会有一个应聘者,他能直观的认识树这种结构,而且可以把我的问题形象化,图形化的描述出来.当然他或许对于某些操作的时间复杂度不甚了解,但是对于问题他却可以立马回应,因为他们脑袋里就有这样的树结构啊~所以他也能拿到工作啊.)

 

As for a book, there is but one: Introduction to Algorithms by Cormen, Leiserson, Rivest, and Stein, otherwise known as CLRS.

至于书嘛,只推荐一本--- <算法导论>
If you want another text, perhaps one with more examples in a specific language, I recommend Robert Sedgewick's Algorithms in C++ orAlgorithms in Java, as appropriate. I prefer CLRS as a text, but you might find these a better teaching aid.

-- 对于某个数据结构,几步:
1、理解该数据结构的基本概念(定义、实现)
2、尝试理解这个数据结构的意义(为什么它会被发明)
3、用这种数据结构解决一些对应的例题(书本上的习题、Online Judge上的水题)
4、尝试用这个数据结构解决一些以往你用别的数据结构解决的问题,能否解决,为什么。
5、再次尝试理解这个数据结构的意义
6、尝试改变这个数据结构以应对各种现实的问题(Online Judge的好题)
7、学好数学,别数都不会数。

> 学习数据结构的几个过程:
1.初级篇
  记住都有哪些算法,解决什么问题;
  去试图解决实际的问题,自然会碰到之前算法解决的问题,使用这些算法。

2.中极篇
  先完成初级篇 ;
  记住算法的具体解决办法;
  实际的问题 如果有与标准算法相似但是不完全一样的,仔细分析差别,修改原有算法。

3.高级篇
  先完成中极篇;
  分析一下算法的解决办法是如何才能想到,最核心和最精妙的地方在哪儿;
  实际的问题如果与标准算法都不太象,仔细想想这个问题的本质,借鉴经典算法精妙之处,自己设计自己要用的算法。

4.骨灰篇
 先完成高级篇;
 忘掉所有算法;
 解决实际问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值