1.知识迁移的能力锻炼好,这也许就是那些所谓学啥都快的原因吧。数据结构B=(D,R),D是数据元素的集合,R是D上二元关系的集合,讲完后接着就是实践-城市表的逻辑结构表示:City=(D,R),D={},R={}。这种方式就是让人不能懒惰。
精华的东西却又看似很简单。
把基础操作实现了,形成算法库。
不要只看,要思考加工,c语言中的typedef struct和Java中的class一样。
数组和顺序表、链表不一样。它们二者基于数组实现。
要养成学完就要用上的习惯,虽然函数里只是简单的一句话在代码中直接写也行,但是要养成这种函数堆砌的习惯。
2.线性表的基本操作学完以后,就是应用。第一个应用删除线性表中所有值为x的元素。自己首先想到的是
i=LocateElem(L,e);ListDelete(L,i,e);但是第一次删除后自己就不知道咋办了,想着用递归,这是自己的思考过程,完全是很混乱的过程。
视频中的解法while(i=LocateElem(L,e)>0)ListDelete(L,i,e);。
while条件循环。for次数循环。善于用while。
多个指针移动,这一遍更精细了,具体怎么移动,如何操作,操作后每个指针如何移动。
以前操作在脑海里都是模模糊糊的,这次能不能清清晰晰的。讲到哪一块,学懂哪一块,可以有疑问,但是不能被疑问疑惑。
一说next,都是指针,以前一说那个结点,直接就用字母标上了,以为字母就是结点。现在明白一说那个结点,这个字母代表的是指针,指向这个结点的指针。
一个指针指向一个结点,指针和结点是共生的,伴随出现的。并不是只有一个指针存活。申请完空间返回一个指针,这个指针指向这个结点,就像java中的引用一样。所以不要疑惑,申请了一个指针,怎么可以指向一个结点呢。多少年来,原来学的一直是错的,多少知识都是被自己模模糊糊的学了。结点包括指针,这是一个整体,而不是自己以前认为的头指针、头结点是分离的,没有关系的。
学完只是一个开始,要用得上,找到用武之地。
算法不要怕麻烦,要画出一个清晰的路线。
对于拆分单链表的应用,自己的想法能粗略的实现(首先根据L定义了三个相邻的变量),但是初始化条件不能保证成立,而且结束条件不能很好的进行判断。贺老师的解法,开始定义比较少的变量,这样利于判断结束条件,其他变量的初始化在循环体中定义。
1.找到循环体 2.初始化需要初始化的变量,其他的放到循环体里初始化 3.确定结束条件。要用纸和笔画出一个清晰的思路,别无他法。
做技术就是要精精细细,来不得半点马虎。
写了这个多个以后,在写的时候还是感觉很陌生,毫无套路一样,好像潜意识里有个东西在阻碍自己前进。我首先问一下自己,在之前写的时候思考过那么多吗。模模糊糊的地方难道要靠天给你搞定吗。
增删查改是基础,然后去进行各种循环和移动。不要嘲笑看不起别人的笨功夫,自己缺的就是笨功夫。
学完一个专题不要继续学下去。反过头来,刷题,刷专题。
while的结束条件是啥,结束的时候那个条件就已经发生 了。p!=null,p为最后一个元素后面的null,p.next!=null,p为最后一个元素,p.next.next!=null,p为倒数第二个元素。
这道题费了我一个多小时,最后写出来了,如果设置一个头结点会很简单,第一个while就不用要了。但是我没这样做。虽然写的很复杂,但是这道题锻炼了我的程序设计能力,第一次while里套if和while,有点烧脑。
自己画了好几次才摸索到思路,应该把一开始就相等和一开始不相等的情况分开,这样写就简单了,有时候觉得复杂是太多逻辑混在一块了,所以不知道从何下手。画了几次知道后,然后就分情况对待,两段代码分开写,下面的承接上面的,就很清晰了。每移动一次都要看有没有相关影响。
不过对于收获,付出的时间是值得的。用加头结点的方法再写一个,加深下印象。while,if,while,for可以任意组合。
2.对于文献的举例就是说明学的东西能用来做什么,应用场景是什么,而不是学后白学,学完都不知道是干嘛的。多思考,东西要经过自己大脑的加工。
3.有问题,找到原因并解决之,最重要的是找到原因。不明白了,模糊了就写一写,不要觉得写了就是自己不行,自己笨蛋,这是不科学的,本来学习就是要理论结合实践的。而不是自己认为的不动手就把什么都学会的。经过这一时间段的工作,自己也能发现,写很多还会有很多问题存在,何况一点都不写,只是在大脑里简单的推演几步呢。要接受这个过程,适应这个过程,用好这个过程。并不是一次成,而且一次能做得很好的一类事情。
4.不是看着小小的收获沾沾自喜,而是意识到只有付出才有收获,感谢自己的付出,然后要更加付出。
5.if包含的块要尽量小,这样易读性好。所以很多程序都是直接判断不成立的情况,直接返回false。而不是判断成立的情况,一坨代码放到if中。嵌套层次越少越好。易读性越好。
6.实在觉得饶了,就像李俊熙一样把业务逻辑的汉语写出来, 照着汉语去写代码。肯定是先在循环体内为空,然后又做了一系列操作,后判断是否为空,所以在一系列操作中可能会报空指针错误。所以得设前一个结点不为空。
7.不要被这种没有来路、虚无缥缈的心思所左右,没有什么益处。可以聊,但是不要情绪化。我不时地告诉自己,你要做一个正直阳光的人,靠正面去吸引人。
8.边界条件要判断,比如为空或者空指针的判断,这也是很多递归情形的终结条件;特殊情况要考虑,比如只有一个结点,两个结点之类的,一定要分析,最后要进入细节的分析里面。
9.两个栈组成队列,只要符合先进先出特性即可,不是要求形态上也和队列一样,这也是做不到的。所以内部实现形态对外是屏蔽的,功能正确即可。这样想的话逻辑就简化了很多,直接往一个栈里push,pop的时候实现就行。
10.串的长度是串中字符的个数,看似很简单的一句话,但是自己没有思考过,没有理解过,所以会出现好像很难理解的样子,但是看上去又是很简单的东西。说明自己以前学的时候就是囫囵吞枣,并没有对基础和细节思考过,烙印在脑子里,只是一直在用而已。
11.for循环的结束条件也可是条件,而不是数字,这样就能达到和while同样的效果。为啥总是想靠一个模模糊糊的过程去搞定一个精密的算法,自己还是爱偷懒。工作中干活的时候也是这样。这个习惯必须得改,不要怕麻烦,要条分缕析,彻底明白。
12.在纸上不停的画,最后得出的结果也就是米鹏那种整体思路: 一个for循环,从前往后找,一样的时候累计一下,不一样的时候,看一下之前累计了多少了,跟保留的一个最大值比较一下。如果大,就把刚刚累计接收的当做最大的。不停的画的过程就是向这个结果思路逼近。贺老师在讲课的时候也会用汉语写出整体思路,然后往里面填充代码,再把串应用这节看下,去抓取一下这个过程。得不到清晰的思路,也不能很好的把思路转化为代码。
13.多米诺骨牌效应,好则更好,坏则更坏,如果出现了坏的苗头,要及时遏止。class和typedef都是在自定义类型,也能理解为自定义数据结构吧。
14.判断串是否相等:
while(p!=null&&q!=null&&p.data!=q.data){
p = p.next;
q = q.next;
}
if(p==null&&q==null) return ture;
else return false;
最后结果的判断,把true的分支直接拎出来返回结果,其他都为else,自己开始还想着各种情况都分析出来,那样可能会有多个分支判断,代码上不精练。以后自己写代码的时候也要有这种思想,抓住主要的东西,使得代码精炼易读。
15.整体思路和细节的混淆。之前的认知:整体思路可以模模糊糊一点,细节再具体做的时候应该清晰。但自己以前的做法是整体思路没有想明白,更没有想完整,或者说没有整体思路的意识,然后就直接陷入“只见树木,不见森林”的细节,细节也是时而模糊,时而清晰,某个细节整体来说还是模糊的,所以会来回混乱好几遍。整体思路--》填充细节。想整体思路的时候要剔除细节的干扰,先写出整体思路,整体思路也是要非常清晰的,然后在各个模块中填充细节。
16.yes,大脑是可以锻炼和训练的,人是可塑的,人是具有很强的学习能力的。看下java是怎么实现串的函数的。
17.数组的定义:int a[N],N决定了数组中的数据元素数目固定,一旦定义,其数据元素数目不再有增减变化。int决定数组中的数据元素具有相同的数据类型int。这些看似很简单,但是以前的学习中从来没有思考过,也没审视过,也是模模糊糊的,没有自己去理解去体会。所以只是能说出来别人的东西,但是没变成自己的东西。
18.这样急匆匆的看完有何效果?和没看有啥区别?
19.现在我要将我的学习计划的机械性思维列出来:
a.按章听贺老师的数据结构课 b.第一步完成后去刷牛客网上这一章的专题,刷题过程中遇到的语言问题学习下 c.按专题模块学习java,并能写出对应的验证demo,实在写不出来的时候才能看以前写的demo d.学MySQL,es,kafka等相关内容(待细化)
20.现在自己学习还有一个问题:学习的时候在改进自己的思维,但是非学习的时间还是在走老思维。这样,新思维的形成过程中不停地受到老思维的影响,会出现之前密友指出的“间断性保持”。所以贺老师在机械性思维小节最后一段很有道理:这种思维将是我们在清清楚楚地做任何事情的时候都需要的,是从事计算机行业工作的需要,也是一种普适的思维,清晰的编程思路可以得来,有序的人生其实也一样。
21.switch会先进行判断,而且只会判断一次。步骤弄清楚,一步一步干嘛的,步骤之间的顺序是什么样的。没有思想,没有代码,代码是思想的体现。
22.能放循环里的步骤都放循环里。要有自己改进的思想。
23.知识都是现成的,都能搜到,这对每个人来说都是公平的,就看你如何学,如何理解了,这是每个人差距的原因。不但要模仿别人的把功能做出来,还要看是如何做出来的,如果下次让我自己开拓去做,我能做出来吗。一定要先理解,还不理解就去demo,只不过是乱撞,一定要努力去理解,不能像以前一样不努力就去Demo。理解了写demo,是验证,有了成功的喜悦,能够理解的更深刻。
24.我努力的在回想多线程的东西,之前自己的思考其实挺多的,但是好像又不记得了,这时候明白了笔记的重要作用。所以以后当有思考的时候还是要及时做笔记的,好记性不如烂笔头。
26.学的东西要努力及早找机会去在各种实践中运用。
27.在一个习惯培养的前期,多用笔记强化自己,提醒自己,把基础打牢,养成思考的习惯后,就需要多即时思考(即时推理)。
28.我们大多数时候都没有自我意识,需要别人指引,这个人可以是别人,也可以是自己。
30.在纸上画算法的过程和代码的对应过程有个鸿沟,如何把画算法的过程转化为代码。而且感觉代码有时候写下来更简单,会让人觉得不可思议,有些难以理解,算法的短短代码可以把画算法的很多过程都包含,觉得有点不可思议。突破方法:每一步对应的代码是什么,写出来,比如初始状态对应的就是初始化代码,遍历过程对应的就是for循环,这样有依有据的清晰的把每一步对应的代码写出来。经常模糊的地方就是:遍历,做操作,按照分析的逻辑写下来先,写的不要总是觉得是错的。
还有自己喜欢幻想好的结果,而不是实事求是的去分析结果。
31.不要试图去死记硬背,这样模糊的记忆会干扰到后面的分析。要理解,而不是记忆。
32.学习算法要过程推代码,而不是代码推过程,理解记忆过程,而不是代码,过程有了,代码功底扎实了,代码自然不是难事。
33.要学的东西很多,不要焦急,排好,一个一个的学扎实了。脑子里有计划,实施的时候不能好高骛远,要一步一步扎实。
34.又学一招:与其要求出当前数组或者矩阵的子数组、子矩阵,不如函数传参的时候直接传入下标(也就是范围),这样通过控制传入的范围就能实现操作子集的作用了,而不是再去另外求子集了。(构建二叉树也重新写下)。
35.要习惯于review自己写的代码,要验证他的正确性,不能认为只要是自己写的就没问题。写完看的时候还是要认认真真对待的。
36. 不管算法都么简单,都要自己亲手实践,只有不断认识错误、不断发现错误,才能不断提高自己的编程能力,不断提高自己的业务水平。踩的坑越多收获越多,也是说的这个道理吧?所以不能害怕错误,程序和其他行业不一样,程序是会出bug的,但是要积极的看待bug,bug是促使进步的东西,而不是令人沮丧的东西。
37.笔记是如何构建的:按照分类,大类里分小类,条分缕析,非常便于按模块复习和查找。但是我没好好利用这个笔记,也没有去及时的补充和更新。
自己对于知识的态度是:收藏了就好了,收藏之后呢?再也没有后续了。有些很有用的帖子和当时的想法完全没有记录下来。绝对是对时间和知识的浪费。想要形成知识网络就从这个做起,分门别类的整理好。一开始就要养成一个良好的习惯,然后就可以整齐有序的一直累加了。你脑海中的知识网络,不应该也是这样吗?以前的收藏的内容在大脑里好像无处安放一样,就是因为没有条理,没有网络层次结构。
38.人就是在这样不停的突破认知,不停的进步的,永远没有止境,知识更没有止境。不可能再像以前一样,学一段就像停滞,不思进取,觉得很牛逼了,觉得能够保持外在条件的上升,这是不现实的。终身学习,持续精进,不断的自我觉察。当着形成习惯,进步就不是一种累了,而是一种自然而然的事情了。也就不会出现脑子里一想一片白,模糊的既视感。
本文作者分享了学习数据结构和算法的心得,强调知识迁移和基础操作的重要性。通过实例分析线性表的操作,探讨了编程中如何避免模糊理解,提倡使用纸笔画出清晰思路。作者指出,学完知识要通过实践应用,建立算法库,并提倡用while循环代替for循环以提高代码可读性。同时,作者反思了自我学习过程中的误区,如忽视基础知识的理解和练习,提醒要勇于面对困难,养成良好的学习和编码习惯。
1386

被折叠的 条评论
为什么被折叠?



