如果你已经掌握了一门编程语言,马上要开始学习数据结构,或者已经学了一部分数据结构,但学得云里雾里,那么推荐你看完这篇文章,它能加深你对数据结构的认知,帮助你快速入门数据结构。
对于刚刚接触数据结构的人,经常会问以下几个问题,我利用这篇文章给大家解答:
- 数据结构是什么?
- 数据结构到底学什么?
- 数据结构和算法,傻傻分不清楚,它们之间有什么区别和关系?
- 数学、英语基础不好,能学数据结构吗,对学数据结构有影响吗?
- 学好数据结构,有什么用?
接下来,我就结合这几个问题,给大家展开讲讲数据结构。
结合自己近 8 年对数据结构的研究,我原创了一整套数据结构和算法教程,它通俗易懂、不学院派,没有晦涩难懂的学术用语,教程提供了完整、可运行的 C 语言程序,非常适合有 C 语言基础、想系统学习数据结构和算法的人。
数据结构和算法教程(C语言版)https://xiexuewu.github.io/
1)数据结构是什么
发展至今,数据结构也没有标准的定义,仁者见仁智者见智。市面上有很多讲解数据结构的书籍和视频,关于数据结构是什么,一些专家给出的答案是:
1) 数据结构是指带结构的数据元素的集合。
2) 数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。
3) 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
每一种回答都试图从不同的视角诠释对“数据结构”的理解,但遗憾地是,只有具备一定数据结构功底的人才能领悟这些话的含义。对于从未接触过数据结构的读者来说,根本不知道在说什么,打死也不可能理解。
很多人学了长时间的数据结构,仍然一脸问号,不知道学数据结构有什么用,归根结底就是没有搞清楚数据结构是什么。
数据结构作为一门独立的学科,是从 1968 年才开始的。在这之前,数据结构的内容散布在其他的计算机课程中,比如编译原理、操作系统等。
数据结构没有想象得那么复杂,它就教会你一件事:如何有效地存储数据。
在数据结构中,所有能被计算机处理的信息都称为数据,比如数值、字符、图像、音频、视频等。
很多人觉得,存储数据是一件很简单的事情,各个编程语言都提供有存储数据的方法,比如常见的变量、数组等,甚至还可以将数据存储到文件中。如果只是单纯地存储数据,的确不是很难。真正的难点在于,存储数据的同时还能将数据之间的关系也存储起来。
举个简单的例子,每家每户都有家谱或者族谱,记录着一个家族世系繁衍的信息,比如图 1 这张家谱图:
存储这张图时,只存储 {张亮 , 张平 , 张晶 , 张磊 , 张华 , 张群} 这些人名是不行的,还要将他们之间的关系也存储起来,比如张亮是张平的父辈、是张磊的祖辈等等。
再比如,大家肯定用过导航软件(比如高德、腾讯地图等),要想实现精确导航,软件必须存储大量的数据,包括各个省、市、区、县的道路、建筑物、红绿灯等位置信息,以及每个地区的天气信息、高速路况信息等等。
这些信息都是数据,而且数据之间的关系错综复杂,能否正确存储这些关系,直接决定着软件导航的精准度。
类似家谱图、道路信息这样的场景,存储数据本身并不难,真正的难点在于如何存储数据之间的关系。通过学习数据结构,你将 get 到很多存储数据的方案,实现在存储数据的同时,还能正确存储数据之间的关系。
总结一下,数据结构是什么,在我看来,它是一门学科,教你如何存储那些具有复杂关系的数据。
数据结构存储数据的思路(思维、思想),可以用任意一种编程语言实现。换句话说,无论你掌握哪种编程语言,也无论你从事什么开发工作,只要你和数据打交道,就一定会用到数据结构。
2) 数据结构到底学什么
数据结构是一门研究数据存储方式的学科,在数据结构看来,数据的存储方式要从以下两个角度来综合分析:
数据的物理结构有 2 种,逻辑结构有 4 种,它们可以随意组合。例如,无关系的数据可以选择集中存放,也可以选择分散存放。针对具有不同物理结构和逻辑结构的数据,数据结构都会给出最恰当的存储方案。学习数据结构,实际上就是学习这些存储数据的方案。
下面是一张数据结构的知识图谱,几乎涵盖了数据结构中所有的存储方案:
注意,想彻底玩转图中罗列的这些存储方案也是不容易的,除了掌握各个存储方案本身,还要学会在各个存储方案中完成对数据的“增删改查”操作,以及用这些存储方案解决一些常见的实际问题(例如字符串的模式匹配、矩阵转置、最小生成树、最短路径等)。庆幸地是,这些知识在数据结构中都会讲到。
数据结构和算法是紧密相关的,学习数据结构的过程中,还要掌握一些常用的算法。关于数据结构与算法的关系和区别,读者可以猛击《数据结构与算法的关系和区别》一文。
总结一下,学习数据结构,就是学习各种存储数据的方案。玩转数据结构,实际开发中遇到的各类数据存储问题都难不倒你。
3) 数据结构和算法的关系和区别
很多教材和视频在讲解数据结构时,都喜欢把数据结构和算法杂糅在一起。例如,很多数据结构教材中都包含一些经典的排序算法和查找算法。这样的课程布置,使很多初学者误认为学数据结构就是在学算法。
首先,可以明确地告诉大家,数据结构和算法是两个完全独立的学科。
图领奖获得者、Pascal 语言之父尼古拉斯·沃斯提出过一个公式程序=数据结构+算法
,它对计算机领域的影响程度,丝毫不亚于爱因斯坦相应论中“E=MC^2”公式对物理学界的影响。从这个公式就能看出,数据结构和算法是不一样的。
数据结构绝不是讲解算法的学科,算法导论才是。算法导论专门研究各类算法,包括排序算法、查找算法、动态规划算法、贪心算法等。
在研究领域上,数据结构和算法有本质上的差别:
- 数据结构研究的是数据的存储问题,比如怎样存储一张家谱图,如何存储导航软件需要的建筑物信息、道路信息、天气信息等;
- 算法研究的是解决问题的方法,比如怎样对特定数据集进行排序,怎样从众多数据中找出目标数据等。
那么,数据结构和算法之间有关联吗,为什么很多教材把他们混在一起讲?
程序=数据结构+算法
既是“数据结构不同于算法”的有力证明,也体现了数据结构和算法之间的联系。
简单来讲,程序是用来解决实际问题的,编写一个完整的程序,既需要用到数据结构的知识,也需要用到算法知识。
举个简单的例子,编写程序计算“1+2+3+4+5”的值。解决这个问题,除了要掌握一门编程语言外,还需要考虑以下两方面的内容:
- 既然计算 1、2、3、4 和 5 的和,首先要将它们存储到计算机中。数据结构中,存储此类数据推荐使用顺序表(一种存储结构,后续会讲)。
- 设计一种算法计算“1+2+3+4+5”的值。比如说,定义一个初始值为 0 的变量 num,依次将 num 和存储的数据相加,最终 num 的值就是所有数据的和。
你看,解决这个问题就同时用到了数据结构和算法。
很多教材在讲解数据结构的过程中,喜欢掺杂一些简单的算法,很大程度上是为了让读者学有所用。程序=数据结构+算法,只学习数据结构是无法编写出程序的,也就无法解决实际中的问题。换句话说,只学习数据结构,无异于纸上谈兵,没有实际意义。
总结一下,数据结构和算法是两个独立的学科,数据结构研究的是数据的存储问题,而算法研究是的解决问题的方法(思路)。
解决实际问题,既需要用到数据结构的知识,也需要用到算法知识,数据结构和算法经常放在一起讲解。我原创的数据结构和算法教程(C语言版),在讲解数据结构的过程中,也会讲解一些关联紧密的算法,让每位读者都能学有所用,用有所成。
数据结构与算法教程,数据结构C语言版教程https://xiexuewu.github.io/
4) 数学、英语基础不好,对学数据结构有影响吗?
很多初学者自认数学、英语基础不好,怀疑这将是学习数据结构不可逾越的大山,对学习数据结构没有足够的信心。
总的来说,数学、英语基础不是学习数据结构的必备条件,但好的基础对学习数据结构大有助益。
这个问题,其实和“英语不好,可以学习编程吗?”同属一类。不可否认,英语基础好对于学习编程确实是很有帮助的,但它并不是学习编程不可跨越的鸿沟。事实上,只有从优秀程序员跃升为顶尖程序员时,英文基础(需要阅读一些英文资料)的桎梏才会凸显出来,但也并非无法克服。数学、英语和数据结构之间的关系也是如此。
注意,英语基础薄弱并不等价于英语 0 基础,如果是这样,那在学习编程的过程中,确实需要适当地恶补一些英语;学习数据结构也是如此,如果数学、英语基础很差(例如仅有小学功底),就需要在学习数据结构的过程中,有意识地恶补一下。这里所谓的恶补,不是让你买数学书、英语书看,而是在学习数据结构的过程中,遇到搞不懂的,再去刻意地翻阅相关资料。
其次,一些读者学习数据结构的初衷,仅仅是想将数据结构应用到自己的项目中。这种情况下,数据基础则更显得无关紧要,因为在实际开发中,很多编程语言都提供有集成数据结构中各种存储结构的库或者模块,例如 C++ 中可以使用 STL 标准库,Python 中可以使用 collections 模块等等。这意味着,如果我们所用的编程语言提供有已封装好的数据结构,则只需简单了解数据结构中各个存储结构的特性,然后调用相关的库或者模块,即可实现最初的目的。
通过前面的学习我们知道,数据结构和算法完全是 2 个独立的学科,只是它们相辅相成(可阅读《数据结构与算法的区别和联系》一节)。读者可能会问,学习数据结构肯定是要学习相关算法的,学习算法不需要有一定的数学基础吗?我认为,学习算法更多的是要求我们具备一定的问题分析能力和空间想象力(可以用画图弥补),很少有算法需要较高的数学功底。
总的来说,无论是学习数据结构还是学习算法,只要读者具备一定的编程能力,都可以学会。而至于英语、数学基础的好坏,有会更好,没有也无需沮丧,依然可以学习数据结构和算法。
5) 学好数据结构,有什么用?
一句话,学好数据结构,你能超越 99% 的程序员!
数据结构并不是一门具体的编程语言,它教会我们的是一种思维方式,即如何以更优的方式存储数据。或者正是由于这个原因,很多读者感觉数据结构虚无缥缈,无法触及,不如学习 Python、Java 等这些编程语言可以随学随用、掷地有声,久而久之觉得学习数据结构没用。
那么,数据结构真的无用吗?当然不是。作为计算机专业最重要的必修学科之一,计算机专业考研的必考知识,以及众多 IT 公司笔、面试的侧重考点,仅仅这些光环,就足以说明学习数据结构的重要性。
毋庸置疑,数据结构不仅有用,更应该是每个程序员必须掌握的基本功。
首先,通过学习数据结构,可以大大拓宽我们的思维模式。掌握了数据结构与算法,我们看待问题的深度、解决问题的角度会大有不同,对于个人逻辑思维的提升,也是质的飞跃。
具体来讲,对于同一个问题,数据结构往往会教给我们不只一种解决思路。举个例子,假设我们需要从众多数据中查找出符合要求的元素,多数人就只能借助数组这种简单的存储结构来实现,而通过学习数据结构我们会知道,解决此类问题既可以通过构建二叉排序树、平衡二叉树、甚至红黑树、B+/B- 树来解决,还可以借助哈希表解决。
再举一个例子,几乎所有的编程语言中都提供有数组这种存储结构,但如果没学过数据结构,就绝不会想到,数组还能以链表的形式使用(也就是静态链表,后续章节会做详细讲解)。
事实上,数据结构也有众多编程语言无法比肩的优势。无论是 Java、Python、C++、PHP 还是其他编程语言,无时无刻不在更新迭代,而数据结构却永远不会过时,其包含的存储数据的思想,已经近乎将所有可能的情况都囊括其中,能解决 99% 的实际场景中有关数据存储的问题。
其次,有很多读者(其中不乏在职的程序员)都会问一个问题,即为什么很多 IT 公司都特别注重对数据结构的考察?读者大可以这样认为:数据结构是众多 IT 公司评判面试人员能力高低的重要工具。
同任何一门编程语言相比,数据结构确实是晦涩难懂的。举个简单的例子,众多学习数据结构的读者中,可能很多人都能快速学会链表、哈希表、二叉树,还能熟练运用大部分的查找算法和排序算法,但能玩转路径规划、字符串匹配、动态规则等复杂问题的人,却凤毛麟角。
因此,要想学好数据结构,不仅要求学员具备良好的编程基础,还必须具有较强的逻辑分析能力和理解能力,甚至还需要具有一定的空间想象能力,可以这么说,能玩转数据结构的人,其综合实力往往都不差。很多大的互联网公司,更看重的往往不是你精通多少种编程语言,而是综合能力,更确切地说是解决问题的能力。
有些读者可能会问,类似 C++ 可以使用 STL 标准库,Python 代码可以使用 Collections 模块等,很多编程语言都可以使用相应的集成数据结构的框架或者模块,直接拿来用不就可以了吗?
事实上,很多在职程序员在开发过程中,都会套用现有的一些集成数据结构的模块或者框架。要知道,适当的使用是可取的,但不能完全依赖,否则知其然而不知其所以然,即便完成再多的项目,也无非是他人代码的搬运工,个人能力很快会进入瓶颈期,再无提升的空间。
再者,对于如何评判一个人编程能力的强弱,不同的人有不同的标准,或许是看中他编写代码的可读性,扩展性、是否健壮等等。
我认为,代码执行性能的好坏无疑能成为众多评判标准中的一个。而想编写出性能高的代码,前提是必须知道如何评判代码的性能,这就不得不使用数据结构中评判代码执行性能的时间复杂性和空间复杂度。
对于某些在职的程序员来说,如果觉得数据结构无用,更多可能是因为你接触的都是一些用户量很少、需要处理的数据量也很少的小项目,实际开发中更注重实现具体的功能,产品的性能要求并非那么苛刻。反之,如果你身处像 BAT 这样的大公司,所开发产品的用户量往往是千万级别甚至亿级别,需要处理的数据量也往往是 TB 甚至 PB 级别,这时产品的性能将是首要考虑的因素,而数据结构和算法的意义将会彻底凸显出来。
别忘了,数据结构也是很多大 IT 公司选拔人才的重要标准。
总结一下,和学习某一门编程语言不同,随学即用,常常会带给你学习的快感。有些知识并非学习了就能立竿见影,但学懂它会让你有整体的提升,数据结构就是这样的知识。
以上这些分享,我都融入到了自己原创的数据结构和算法教程里,结合了自己近 8 年对数据结构的理解,它通俗易懂、不学院派,没有晦涩难懂的学术用语,教程提供了完整、可运行的 C 语言程序,非常适合有 C 语言基础、想系统学习数据结构和算法的人。
数据结构与算法教程,数据结构C语言版教程!https://xiexuewu.github.io/
如果大家对数据结构还有什么疑问,可以在评论区问我,我肯定知无不言。