抽象数据类型
示例
在编程语言(或库)和教科书中,常见的几个抽象数据类型如下:
关联数组
复数
容器
双端队列
列表
Multimap
优先队列
队列
集合
堆栈
字符串
树
接口和实现的分离
实现于程序时,抽象数据类型只显现出其接口,并将实现加以隐藏。用户只需关心它的接口,而不是如何实现。未来更可以改变实现的方式。(其支持信息隐藏原理,或保护程序免受变化的冲击。)
抽象数据类型的强处在于对用户隐藏了实现细节,仅公开其接口。这表示抽象数据类型可以用各种方法来实现,只要遵循其接口,就不会影响到用户。
在抽象数据类型和数据结构之间,有一个实现上的微妙差别。例如,列表的抽象数据类型可以数组为基础、或者使用链表来实现。列表即是一种具良好运算(加入元素、移除元素等等)定义的抽象数据类型。链表是以指针为基础的数据结构,且可用来创建一个列表。链表常用于列表的抽象数据类型。
同样地,二叉树搜索法的抽象数据结构可以几个方式实现:二叉树、AVL树、红黑树、数组等等。且无须关心其实现,二叉树搜索法总是有相同的运算(插入、移除、查找等等)。
从实现中分离出接口,并不表示用户不该知道实现的方法,而是用户不能依赖于实现细节。例如,一个抽象数据类型可以用脚本语言创建,或其它可以被反编译的语言(如C语言)。即使用户可发现实现的方法,只要所有客户端程序遵循该接口,且改变实现方式时不会产生影响,那就仍是抽象数据类型。
在面向对象的用语中,抽象数据类型相当于类别;抽象数据类型的实体就相当于对象。某些语言包含了用于宣告抽象数据类型的构造函数。例如,C++ 和 Java 为此提供了类的构造函数。
抽象数据结构
抽象数据结构即根据所要运算的数据以及其计算复杂性所定义的抽象存储区,而不关心具体的数据结构的实现。
就实现高效率的算法而言,对数据结构的选择相当重要。抽象数据结构的选择,决定了高效率的算法的设计,和估计其计算复杂性。
这个概念与编程语言理论中所使用的抽象数据类型非常接近,大致上抽象数据结构和抽象数据类型的名称,和具体的数据结构的名称一致。
内置抽象数据类型
一部分抽象数据类型在程序设计中相当普遍且实用,所以在某些编程语言中,成为原生类型、或加进标准库中。例如,Perl 的数组可以用列表或双端队列之类的抽象数据类型来实现,散列表也可以用 Map 或 Table 来做。C++ 标准库和 Java 库也提供了列表、堆栈、队列、Map、优先权队列和字符串。
实际示例
作为抽象数据类型的有理数
有理数(可以 a/b 格式表示的数,且 a 和 b 都是整数)本来是不能在电脑中表示出来。不过可以合理的抽象数据类型来定义,如下。
构造:使用两个整数 a 与 b 创建实体,其中 a 为分子,b 为分母。
运算:加法、减法、乘法、除法、乘幕、比较、约分,转成实数(浮点数)。
要完成整个规格,就要根据数据来定义所有的运算。例如,当两个有理数 a/b 和 c/d 相乘时,相乘的结果就要定义为 ( a c ) / ( b d )。还有输入、输出、先决条件、后置条件,以及对抽象数据类型的各种假定。
堆栈
接口
堆栈的抽象数据类型接口,以 C 语法编写:
用法
抽象数据类型可以如下方式使用:
各种实现
上述堆栈的抽象数据类型,一开始可以使用数组来实现,然后改用链表,而不会伤到任何用户的代码。有多少方法可以实现抽象数据类型,取决于编程语言。例如,上述示例可使用 C 编写一个结构,以及随同的一组数据结构,可使用数组或链表来存放记录;当构造函数函数返回一个抽象句柄时,就对用户隐藏了真实的实现过程。
参阅
抽象化
免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。
- 有价值
- 一般般
- 没价值