今天开始认真读这本清华版的数据结构,严蔚敏和吴伟民编著。也许你会奇怪我为什么会选择这本C语言描述的数据结构书,现在的数据结构不都用面向对象语言描述吗?其实这本书不是我选的,而是我参加的机试指定的参考书。不过对于本书选用的语言,我倒有自己的看法。用C语言描述显然有很多不便,但是在一个充斥着用OO描述数据结构的世界里,从OO中抽身出来用C看待数据结构的思想,也许更能看清数据结构的本质。
好了,言归正传。在今天这第一篇文章里,我来探讨一下数据结构的基本概念。作者一开篇就归纳了计算机解题的一般步骤:“首先要从具体问题抽象出一个适当的数学模型,然后设计一个解此数学模型的算法,最后编出程序,进行测试、调试直至得到最终解答。”我把它再进一步归纳一下,就是:抽象数学模型——设计算法——编写程序。这个思路非常重要,除了一些非常简单的问题,所有的程序设计都应该遵循这三个基本步骤。我们平时写程序常犯的错误是忽略第一个或第二个步骤,或者更甚者,前两个都忽略。
在设计数学模型的过程中,实际上就引出了数据结构的概念。本书中作者给出的定义是:“简单来说,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。”国内的教材为了语言上的严谨常常把话说得很难懂。请大家注意这句话里的这几个关键词:1)非数值计算,这说明了数据结构这门学科的应用范围,如果你想解一个线性方程组,大概很难直接找到合适的数据结构;2)操作对象,也就是问题中的数据及其表示的形式;3)关系,即数据间的关系;4)操作,即针对数据的操作。
把以上的定义用公式写出来,就是
Data_Structure = (D, S)
其中D是数据元素的有限集,S是D上关系的有限集。所以在设计数据结构时,首要的任务就是找出要操作的数据,其次是挖掘出数据间的关系。这两步完成以后,数据的逻辑结构就定下来了。其中数据间的结构有以下几种:
-
集合,这和数学中的集合概念是一致的;
-
线性结构,即数据元素之间一对一的关系;
-
树形结构,即数据元素之间一对多的关系;
-
图状结构或网状结构,即数据元素之间多对多的关系。
然而只有逻辑结构是不够的,程序要能够运行,必须把数据的逻辑结构在计算机中表示出来,也就是设计物理结构。大多数高级语言都对数据的物理结构有较好支持,如各种数据类型。作者在解释数据类型的概念时说到:“引入数据类型的目的,从硬件的角度看,是作为解释计算机内存中信息含义的一种手段,而对使用数据类型的用户来说,实现了信息的隐蔽,即将一切用户不必了解的细节都封装在类型中。”这个概括非常精辟,从中可以看出以后的OOP只是在更高层次上对信息的封装和隐蔽。
对数据类型进一步扩展,作者引出了抽象数据类型的概念。抽象数据类型(ADT)是指一个数学模型以及定义在该模型上的一组操作。在引入抽象数据类型后,使逻辑结构更加独立,从而让程序员可以更加专注于逻辑结构的设计。把抽象数据类型用公式表示出来,就是
(D, S, P)
其中D是数据对象,S是D上的关系集,P是对D的基本操作集。如果计算机解题一定要遵循一个通用的模式的话,上面这个式子就给出了答案。