数据结构与算法——第1章-数据结构与算法的学习建议(1.3)

一 概述

1
2
3
1.如何高效学习数据结构
2.数学不好有影响吗?
3.学好数据结构,超越 99% 的程序员

二 如何高效学习数据结构

2.1 概念

1
2
3
4
5
6
7
8
9
学习数据结构和算法有一个很重要的前提:至少熟练掌握一门编程语言。

本教程以 C 语言作为教学语言,当然也可以在掌握 C++、Python 等语言的基础上学习数据结构和算法。
因为无论是数据结构还是算法,它教会我们的是解决问题的思想,并不挂靠某一门具体的编程语言。
掌握任何一门编程语言后,都可以学习数据结构和算法。

初学时,多动笔动手,必要时画图、做到心中有数。如画一个存有{1,2,3,4} 数据的链表:

假设想删除存储元素 3 的结点,也可以先通过画图来实现:

2.2 图示

链表 画图

2.3 过程分析

1
2
3
4
5
6
7
8
9
10
整个画图的过程也是思考如何通过程序实现删除指定节点的过程:

-先要找到它的前驱结点(结点 2)并用一个指针 p 来标记
-借助指针 p,可以顺利找到结点 3,因为它最终要被摘除,
考虑到该结点占用的空间要手动释放,因此还要用一个指针 q 来标记它
-借助指针 p 和 q(图中的第 3 步),就可以成功将目标结点摘下来
-最后借助指针 q,可以释放被删除节点所占用的存储空间

想要学好数据结构,除了找一套适合自己的学习资料和学习方法外,更要有一种坚持的精神,
第一次你学习理解的时候可能觉得很难,但不断重复回顾之后,就渐渐明白了。

三 数学不好有影响吗?

3.1 数学是学校数据结构的必要条件吗

1
2
3
4
5
6
7
8
数学基础不是学习数据结构的必备条件,但好的数据基础对学习数据结构大有助益。

这个问题其实和“英语不好,可以学习编程吗?”类似。
不可否认,英语基础好对于学习编程确实很有帮助,但编程大神也不一定很懂英语。数学和数据结构之间的关系也是如此。

注意,如果是英语 0 基础,那在学习编程的过程中确实需要适当地恶补一些英语;学习数据结构也是如此,
如果数学基础很差(例如仅有小学数学水平),就需要在学习数据结构的过程中,有意识地恶补一下数学。
所谓的恶补,是指在学习数据结构的过程中,遇到搞不懂的数学运算,再去刻意地翻阅相关资料。

3.2 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
前面已经详细的讲解了如何用“大 O 记法”来评判一个算法的时间复杂度,下面 C 语言代码的时间复杂度是多少?

i = 1;
while( i < n ){
i = i * 2;
}

对于此段代码,只需要求出while循环中代码(第3行代码)执行的次数,即可得到这段代码的时间复杂度。
可以看到,循环条件为i<n,而变量i的值每经历一次循环都会翻倍,
因此假设有一个临界值m,能恰好使2m=n,此时循环将会终止,程序运行结束。

因此,求这段代码的时间复杂度,只需要求出m的值即可。
这就需要具备对数运算的能力,由2m=n得m=log2n,简化m的值并最终得出此段程序的时间复杂度为O(logn)。
此时,如果读者无法理解m值的由来,就需要恶补一下关于数学中对数运算的相关知识。

其次,有些同学学习数据结构的初衷仅仅是想将数据结构应用到自己的项目中。
这种情况下,数学基础则更显得无关紧要,
因为在实际开发中,很多编程语言都提供有集成数据结构中各种存储结构的库或模块,
例如 C++ 中可以使用 STL 标准库,Python 中可以使用 collections 模块等。
如果所用的编程语言提供有已封装好的数据结构,则只需简单了解数据结构中各个存储结构的特性,
然后调用相关的库或模块,即可实现最初的目的。

四 学好数据结构,超越 99% 的程序员

数据结构不仅有用,更应该是每个程序员必须掌握的基本功。

4.1 提升逻辑思维

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
学习数据结构可以大大拓宽我们的思维模式。
掌握数据结构与算法,看待问题的深度、解决问题的角度会大有不同,对于个人逻辑思维的提升也是质的飞跃。

对于同一个问题,数据结构往往教给我们不只一种解决思路。

举个例子,假设需要从众多数据中查找出符合要求的元素,
多数人就只能借助数组这种简单的存储结构来实现,而通过学习数据结构我们会知道,
解决此类问题既可以通过构建二叉排序树、平衡二叉树、甚至红黑树、B+/B- 树来解决,还可以借助哈希表解决。

再举一个例子,几乎所有的编程语言中都提供有数组这种存储结构,
但如果没学过数据结构,就绝不会想到,数组还能以链表(静态链表)的形式使用。

事实上,数据结构也有众多编程语言无法比肩的优势。编程语言(无论是 Python、C++ 还是其他)在不断更新迭代,
而数据结构却永远不会过时,其包含的存储数据的思想几乎将所有可能的情况都考虑到,
能解决 99% 的实际场景中有关数据存储的问题。

4.2 能力高低的分水岭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
同任何一门编程语言相比,数据结构确实是晦涩难懂。
众多学习数据结构的同学中,很多人都能快速学会链表、哈希表、二叉树,还能熟练运用大部分的查找算法和排序算法,
但能玩转路径规划、字符串匹配、动态规则等复杂问题的,却凤毛麟角。

因此,要想学好数据结构,不仅要求具备良好的编程基础,还必须具有较强的逻辑分析能力和理解能力,
甚至还需要具有一定的空间想象能力,可以说,能玩转数据结构的人,其综合实力往往都不差。

很多大的互联网公司,更看重的往往不是你精通多少种编程语言,而是综合能力,更确切地说是解决问题的能力。

有同学可能会有疑惑,类似 C++ 可以使用 STL 标准库,Python 代码可以使用 Collections 模块等,
很多编程语言都可以使用相应的集成数据结构的框架或模块,直接拿来用不就可以了吗?

事实上,在开发过程中都会套用现有的一些集成数据结构的模块或框架,
但如果没弄懂其中的原理,也就无法根据实际碰到的问题做出使用决策,且无法随着问题的改变而做适当的更改;
此时即便完成再多的项目,也无非是他人代码的搬运工,个人能力很快会进入瓶颈期。

4.3 程序性能好坏的评判标准

1
2
3
4
5
6
7
8
9
10
11
12
13
对于如何评判一个人编程能力的强弱,不同的人有不同的标准,或许是看中他编写代码的可读性、扩展性、是否健壮等。

代码执行性能的好坏无疑能成为众多评判标准中的一个。
而想编写出性能高的代码,前提必须知道如何评判代码的性能,
因此需使用数据结构中评判代码执行性能的时间复杂性和空间复杂度。

如果觉得数据结构无用,更多可能是因为你接触的都是一些用户量很少、
需要处理的数据量也很少的小项目,实际开发中更注重实现具体的功能,产品的性能要求并非那么苛刻。
反之,如果你身处像 BAT 这样的大公司,所开发产品的用户量往往是千万级别甚至亿级别,
需要处理的数据量也往往是 TB 甚至 PB 级别,这时产品的性能将是首要考虑的因素,
而数据结构和算法的意义将会彻底凸显出来。

数据结构也是很多大 IT 公司选拔人才的重要标准。

五 参考

  • CSDN—数据结构与算法的学习建议