数据结构个人学习推荐

您所在的位置:网站首页 mooc刷课会被发现吗 数据结构个人学习推荐

数据结构个人学习推荐

2023-02-22 08:25| 来源: 网络整理| 查看: 265

目录学好这门课的重要性学习方法多看图例并动笔画图步步为营且不断重复Show me your code!尝试输出所学知识常见的问题C 都还给老师了,还需要返工吗?需不需要先学某门语言再开始学?代码都看不懂,无从下手咋办?资料推荐书籍推荐《数据结构(C语言版)》——严蔚敏、李冬梅《大话数据结构》——程杰《剑指 Offer》——何海涛《数据结构高分笔记》——天勤论坛《漫画算法:小灰的算法之旅》——魏梦舒《数据结构(C++语言版)》——邓俊辉《算法(第4版)》《算法导论》课程推荐数据结构-浙江大学数据结构与算法基础-青岛大学王卓数据结构-王道计算机考研我的博客笔记 这篇博客只是分享一些个人的学习经验,推荐一些资料,带有强烈的个人主观感受在里面,仅供参考。

学好这门课的重要性

和计算机网络不一样,这门课让我去讨论它的重要性,一时间还真不知道怎么说。说它是后面搞开发要具备的基础吧,但很多编程语言其实都有封装好这些数据结构的实现,例如 C++ 的 STL 库,Java 有集合类(Collection 和 Map)。说是锻炼计算机思维之类的方面吧,但是往往是只可意会不可言传的,我好像也没什么直接的感受。 先从一些实际的角度上说:

首先这门课是计算机类专业的专业必修基础课,也就是说只要是计算机类的专业都是要学习数据结构的。所以无论后面的发展方向是否需要用到这些知识,至少得先把这门课过了。 对于就业而言,无论是问答、手撕还是现场敲,面试开发岗基本上都会考查算法题,很多技术的底层原理也都是基于相应的数据结构实现的。 对于研究生考试而言,在科目“408”中数据结构占到 45 分,和计算机组成原理一样是占比最高的科目,大部分自命题的学校也会考查甚至是只考察数据结构。在复试中的笔试或上机环节也会大量考查数据结构的代码,面试中专业课问答的环节这门课也非常容易提问。 对数据结构或者相关的研究领域,想要从事相关的科研工作肯定得有非常扎实的数据结构、算法的基础。 对于程序设计类学科竞赛,例如 ICPC、CCPC、程序设计天梯赛、蓝桥杯,数据结构是必须要掌握的基础知识。

再从比较“虚”的角度上来看,编程语言和具体的技术相当于计算机专业的“招式”,而数据结构、算法之类的理论相当于“内功”。我们都说“程序 = 数据结构 + 算法”,不同情景下的程序需要处理的数据各有其特点,选用合适的数据结构才能更好地组织数据或利用其特性满足需求。同时时间复杂度、空间复杂度分析贯穿着整门课程,体现了一种优化的思想,在开发应用时除了利用主流技术和框架,在对他们进行排列组合或者编写业务流的代码时也需要很注意在时间和空间上的开销。在很多时候,某个功能的少许时空上的优化,很可能在某个量级的数据下能显著地提升效率。 在其他很多的理论课中,也都能或多或少地看到数据结构的影子,例如数据库的索引、操作系统的堆栈和队列、计算机网络中的报文格式等。很多计算机的理论和技术都是相互渗透或需要协同工作的,相信学好数据结构对学习其他计算机理论课也有很大的帮助。

学习方法 多看图例并动笔画图

这门课你可以把它当做是我给你一些数据,你通过一些抽象的数据结构来组织他们,使这些数据能够在计算机中抽象出现实中的意义,或者能够借助这些结构的特性来有效解决某些问题。所以这里面包括很多计算机的技术和理论,都包含着对现实的抽象,因此如果没法很好地理解抽象后的效果,也就很难理解这些算法。例如看如下一段代码:

typedef struct BiTNode { ElemType data; //数据域 ChildPtr *lchild,*rchild; //左右孩子的指针域 //可以开个指针域指向双亲,变为三叉链表 }BiTNode, *BiTree;

在没有学习这门课之前,你可能很难想象出就这么几行代码就能将数据以“二叉树”的形式组织,如下面这张图所示。 所以这些数据结构乍一看理解不了很正常,因为它们都是抽象之后的东西,想要看懂就需要化抽象为具体。此时一个具体的例子和逐步推进的算法图例能起到很重要的作用,先理解某个例子在算法中的执行过程,就有助于你在思路上推广到通用的、抽象的算法上。例如单链表插入新结点的图例如下所示,通过画图你就能理解 2 个关键操作的作用,以及它们不能调换顺序的原因。 有时候当算法比较复杂时,可能你一时间也没法把图画好,或者是数据量稍微大一些图会变得不好画。此时可以利用一些数据结构可视化工具,例如我学这门课的时候主要用了VisuAlgo,你可以输入一组数据然后逐步查看每一步都发生了什么事。

步步为营且不断重复

数据结构和 C 语言这类技术课有着本质上的区别,我认为它是一门需要通过编程来掌握的理论课,所以在算法上的理解和编程上的实践都很重要。这门课的信息量相对是比较大的,学习时感到“消化不良”是常事。对学习这门课本身其实可以和中学的学习差不多,预习肯定是很重要的,至少要先知道这种数据结构或算法要解决一件什么事情,否则上课很容易掉线。因为知识量比较大,在书本上圈圈画画、做笔记、整理笔记本也需要看情况选择,也要通过一些例题和作业来巩固。这些肯定屏幕前的你是懂的,但是知道和是否有付出行动是两个完全不同的维度。 需要强调的一点是,如果让我挑一个最重要的章节,那一定是线性表。简单地说,线性表、树、图分别是数据的一对一、一对多、多对多的关系,树和图可以看做是线性表的推广,线性表也可以看做树和图的特例。例如图中的结构是一种特殊的二叉树——斜树,是一种所有结点都只有左(右)子树的二叉树,不难看出从表面上看它就是线性表。 线性表(尤其是单链表)的基操是极其重要的,栈和队列本身就是特殊的线性表,后面的树和图把它们的代码段的粒度切得很细时,会发现这些操作和线性表的操作是紧密联系的。所以线性表掌握得情况如何,其实基本上能决定后续这门课的学习是否能有较好的节奏。所以这门课一定要从一开始就紧紧跟着,前面放松了后续雪球只会越滚越大,很容易导致直接摆烂。 当然这门课本身内容比较多,也不用想着一两遍就全部记下来,肯定也是需要不断多次重复才能较好地掌握。每次的学习都是有效果的,在后期重复复习的时候,过同一个知识点肯定效率会更高。在脑中提取的速度越快,复习时捡起来的速度越快,也能从侧面证明掌握的情况是比较好的。

Show me your code!

弄懂了这些算法的原理,做对了纸质的作业就算是完全掌握了吗?如果是由人的肉身去执行这些算法,不难看出这是一件啰嗦且费劲的事情,我们的最终目的是要让计算机来执行这些代码,这肯定比人有效率得太多太多。所以真正要看看自己掌握的如何,一定要有足够的编程量,看看你的所学能不能解决问题。因为题目难度有别,对知识的掌握也是循序渐进的,所以对于一道具体的题目,可以按照下面的流程来要求完成。 借鉴学习他人的优秀代码是没问题的,毕竟一道超出现在能力的题目很难不靠外力憋出来。不过切记,这和直接复制粘贴交作业完全是两码事。同时看懂算法和动手写代码也存在明显的相互作用,尤其是在懵懂和看懂之间的“暧昧”状态时,放下书本敲点代码能帮你理顺算法的思路和流程。我刚学链表的时候也有这么一段时间,我就找了个题集把链表的基操写出肌肉记忆,回头再看链表的基操就能比较顺畅地理解了。 所以数据结构学不进去的原因,也有可能是学习时根本没有动手写过代码,而不是所谓的“基础差”、“记不下”和“看不懂”的问题。

尝试输出所学知识

我们学习很多的理论和技术的最终目的,往往都是为了能在工作或生活中利用它们满足需求或者发现、解决新的问题。尤其是对于计算机类这门较为“务实”的学科,学习这些知识都是为了让我们能更好地利用计算机。所以你可能理解了这门课的很多知识,写了很多作业也刷了一些题目,但是如果不能进行输出,其实就结果而言和没有学习这门课是一样的。 在理论方面也可以用知识输出的方式帮助自己检验学习效果,巩固对知识的理解。如果你要把某个知识点或题目 100% 地教会别人,你对它的理解一定是需要超过 200% 的。因此在学习过程中你可以有意识地寻找和他人讨论或讲解的机会,或者制作一些复习提纲或者知识笔记之类的,这些都是知识输出的方式。我之前学这门课是在疫情居家学习的时候,当时我写博客就写得非常上头,由于需要翻阅很多资料来回阅读,所以写完博客就对知识点比较熟悉了。在后期进行应用或者考试时,也可以通过读这些博客的方式快速复习或检索出需要的内容。 在写代码方面就更不用说了,学习数据结构的一大目的就是为了更好地组织数据。平时写的编程题确实能帮助你学好这门课,但是毕竟题目只是一个小的、特定的情景,工作或生活中的情景远比题目大得多或复杂得多。因此学完这些知识,更重要的是结合自己现有的技术做一个较为完整的应用,至少是一个综合度和工作量较大的课程设计。送分级别的课程设计题目,或做出的成品只能勉强达到及格的程度,肯定是不能达到学以致用的要求。

常见的问题 C 都还给老师了,还需要返工吗?

可以但不推荐,现在再去返工 C 语言的价值已经很小了。虽然学习时需要用 C 语言实现数据结构(先开 C 后学数据结构的情况),但是只要把握好学习绪论、时空复杂度和线性表的时间,数据结构的内容可以反过来帮助你熟练 C 语言。 一种数据结构的实现可链式存储也可以顺序存储,顺序结构在 C 语言一般使用数组实现,例如:

//顺序表按照元素查找 Position LocateElem(List L, ElementType e) { int i = 0; for (Position i = 0; i Last; i++) { if (L->Data[i] == e) { return i; } } return 0; }

链式结构需要用到很多指针,例如:

//头插法建链表 void CreateListF(LinkList& L, int n) { LinkList head, ptr; head = new(LNode); //创建头结点 head->next = NULL; //初始化头结点的后继为NULL for (int i = 0; i < n; i++) { ptr = new(LNode); //创建新结点 cin >> ptr->data; ptr->next = head->next; //连接表身 head->next = ptr; //将新结点插到表头 } L = head; }

定义数据结构时需要会写结构体,例如:

//定义单链表结点类型 typedf struct LNode { ElemType data; //数据域,存放数据 struct LNode *next; //指针域,指向后继结点 }LinkList,*List;

同时也不难看出,实现这些结构的功能也肯定不会缺少分支和循环。因此我认为认真把线性表吃透,代码模仿着多写一写,自然就会熟悉学习这门课需要的 C 语言语法。一开始也不用太苛求自己能写出线性表的各种操作,而是先看懂每组代码段都是些什么功能,具体的语法怎么用再回去查即可。 当然这样做肯定一开始还是会很痛苦的,这也意味着在学完线性表之前你需要挤出更多的时间,花费更多的心血才能把必要的基础补上来。其实很多的方法技巧起到的效果都是少走弯路、省些力气,但不意味着过程会很轻松。但我相信如果回头去学这门上学期因为种种原因掌握得不是很好的课,可能重新看完教材半新个学期都过去了,也耽误了新课程的学习。学习新的知识,换一种新的学习思路,可能你的编程之路会就此开启一个新的起点。

需不需要先学某门语言再开始学?

不需要,只是说你掌握了更多编程语言的时候,可选的学习资料也会变多而已。算法可以理解为解决问题的具体步骤或策略,这个步骤不会因为你换了一种实现方式就失效了。例如定义单链表,用 C 写是这样的:

//定义单链表结点类型 typedf struct LNode { ElemType data; //数据域,存放数据 struct LNode *next; //指针域,指向后继结点 }LinkList,*List;

用 Python 写是这样的:

class ListNode: def __init__(self, val, next): self.val = val self.next = next class LinkedList: def __init__(self): self.head = None

而且他们分别是基于面向过程和面向对象实现的,但它们都实现了链表结构。所以学习这门课并没有编程语言的限制,用 Java、Pascal、JavaScript 和世界上最好的语言 PHP 都可以。在具体用代码实现之前,首先要把算法的原理和一些典型的例子搞清楚。 如果是先开 C 后学数据结构的情况,掌握 C、C++ 面向过程和 STL 库就完全够用,可以参考我之前写过的博客《C++面向过程编程》和《C++ STL 库快速上手》。如果你学了其他编程语言,也可以选择其他资料来进行学习,例如学过 C++ 可以选择邓俊辉的《数据结构(C++语言版)》,学过 Java 可以选择《算法(第4版)》。

代码都看不懂,无从下手咋办?

这个问题通常有两种情况,第一种是算法本身没弄懂,第二种是可能代码比较长被吓坏了。如果你没有先理清对应的算法原理,自然也无法知道不同的代码段需要实现什么功能。有的算法的实现思想是比较巧妙的,用代码实现起来不一定会很长,就很容易看的云里雾里。所以这种情况就需要回去再看看算法原理和一些例子,一个方法是可以先回到一组具体的测试数据上,甚至是特例也行。先假设此时算法的输入只有这一种情况,按照这个例子的步骤强行硬编码复现算法,接着在尝试第二个特例。我相信这样搞个两三组数据,你再把这些版本的代码改成通用的即可。 不过我觉得在课堂学习时,更常见的情况是后者,尤其是到了图章节的一些算法更是吓人。首先需要认识到复杂的功能都是用简单的功能排列组合而成,因此可以先把课本上的代码划分为很多代码段。例如合并两个线性表,你可以先实现获取表的长度、读取线性表第 i 个元素、判断元素 e 是否存在、插入链表这 4 个函数,然后通过排列组合得到代码:

void unionList(List &L1,List L2) { int len_a,len_b; int i; ElemType e; len_a = ListLength(L1); //获取表长 len_b = ListLength(L2); for (i = 1; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3