关于ADT的一些简单解释及理解
笔者写这篇文章的初衷是帮助刚刚接触软件构造课程的小白通俗易懂地解释关于ADT方面地知识(才不是为了作业呢)。虽然说上课老师讲的很不错,课件ppt也都提供了,本来也不需要我在这里过多的解释什么,但是ppt上大多是大段的英文,即便有少量中文来标记重要的知识点,但是如果不阅读那些英文的话是没有办法很好的理解的。笔者就当抛砖引玉,简单谈谈自己关于抽象数据类型(ADT)的理解。
最早接触到ADT概念的应该是大二上的数据结构课程上,当时只学了个概念,但是并没有很好的理解其具体意思。
一.ADT简介与特征
抽象数据类型(Abstract Data Type,简称ADT):是计算机科学中具有类似行为的特定类别的数据结构的数学模型;或者具有类似语义的一种或多种程序设计语言的数据类型。抽象数据类型是间接定义的,通过其上的可执行的操作以及这些操作的效果的数学约束(与可能的代价)。
定义显然是不直观的。毕竟人家叫抽象数据类型嘛,肯定和数据类型有一定的关联。我们一般用的int啊,double啊这些,称为数据类型,有什么作用呢?显然是为了表示数据。short表示的范围小,int表示的范围大;int表示整数,double可以表示浮点数······可以发现,数据类型强调数据的“具体表示”。但是,ADT既有“抽象”二字,与之就有不同之处。ADT更加强调作用在数据上的“操作集合”,我们并不关心数据在ADT中是如何存储的,而ADT数据如何操作则是我们的重点。例如我们常常自己定义了一个myString来进行String操作。如果把myString看成一个抽象数据类型,那么我们完全不关心String是char数组存储,还是链表存储or其他。我们只关心操作,如求字符串长度啊,打印字符串啊,取子串等。ADT是由操作定义的,与其内部如何实现无关!
二.ADT的分类与组成
1.ADT的分类
我们通常将ADT分为不可改变的(immutable)和可改变的(mutable)。在不可改变的情况下,当我们需要改变值的时候必须建立一个新的对象;而可改变的情况则直接改变该对象的值。
2.ADT的组成
ADT的组成,如果用形式化的定义去描述,理解起来可能会比较困难,笔者希望通过生动的比喻来通俗的阐述以下这些名词,如果有粗糙之处还请见谅。我们建立一个“一桶水彩笔”的ADT。
a.构造器(creator):我们声明了一个具体的一桶水彩笔 ,可以理解为笔的初始化,他不再是一个概念了,而是一个真实的存在了,无中生有。
b.生产器(producer):生产器针对已经存在的实物。例如我这里有两桶笔,我可以通过生产器将他们合并,成为一桶笔。注意我们的ADT是以“一桶水彩笔”作为概念的,因此这里合成的“一同水彩笔”其实也是新的对象,但是是从已经真实存在的“两桶水彩笔”出发的。
c.观察器(observer):观察已经存在的实物。例如一桶水彩笔里的颜色,数量等等。
d.变值器(mutator):对已经存在的实物的改变,例如改变一桶水彩笔里笔的数量,颜色等等。
3.一些笔者曾陷入的误区,提醒
a.在PPT中曾经说到int是不可改变的,但是笔者一直不明白。因为数字我们知道是可以相加减的,怎么能说他是不可改变的呢。但其实,这个不可改变是针对对象而言的,对于1这个数来说,他既是个数,也是一个对象,1永远是1,是不会改变的。而像list表来说,一个表的元素可以添加可以删除,改变了这个对象,因此称为是可改变的。
b.不可改变的ADT不会含有变值器。这个规则其实与a有异曲同工之妙。因为是不可改变的,因此不可能存在变值器能够改变他的值。通常来说变值器的返回值是void类型的,但也有少数会存在返回值。
三.表示独立性(representation Independence)
表示独立性: 用户在使用 ADT 时无需考虑其内部如何实现, ADT 内部表示的变化不应影响外部规则和客户端。
简单来说就是数据类型的封装性。就像我们在定义int类型的数据时只要简单的声明就可以了,并不用深究深层的原理是什么;在使用抽象数据类型时用户也不需要知道内部是如何完成的,只需要声明就可以了,而且我们知道ADT针对操作集合,因此在使用操作时也只需要满足外部的要求就可以了,并不需要了解内部构造。
四.关于RI和AF(Rep Invariant and Abstraction Function)
不得不说,,虽然身为中国人笔者很自豪,但很多时候不懂英语确实对学习有些影响(笔者英语太差了呜呜)。其实一些很简单的概念常常会因为英文的复杂而感到头大,呃呃,回归正题。
首先,因为上述的表示独立性,即用户使用ADT时无需考虑内部的实现,因此对客户的数据的表示和对内部的数据的存储可能会有不同。我们把面向客户的数据空间称为抽象空间(A),而对内部的存储以及处理的数据空间称为表示空间(R)。对于客户来说,只要程序能够输出正确的值就可以了,但是对于程序员来说,内部表示空间的存储才是着手的地方。
AF(Abstraction Function)实际上是内部空间(R)到抽象空间(A)的一个映射。这个映射在一定程度上可以说是程序的目的,也就是我们设计程序的原因。如下图是一个输入字符串输出字符串里字符的集合。 AF : R->A
由A和R的定义我们能够简单分析出,R中的每一个元素未必能够映射到A中,但是A中的元素一定是R中的元素映射过去的,这个映射一定是一个满射,但未必是单射,双射。那么,怎么判断R中的元素是有效的呢(能够映射到A中)?
由上述这个问题,RI应运而生。RI就是用来判断R空间中的数据是否合法的,这一步也是在ADT的内部完成,不需要透露给客户端。如下图,RI就将具有重复字符的字符串给不合法化了。
RI: R->boolean
因此,在编写具有普适性的ADT时,在代码内部一定要把RI解释的简单又清楚,这样才方便后续的程序员了解规则。
五.结语
至此,笔者将ADT的大致模样简单的描述了一下。关于ADT的设计原则,ADT中的不变量等笔者觉得学习起来没有上述知识那么复杂,因此并没有过多介绍,希望各位大佬不吝赐教,各位小白读了笔者这篇文章能够有所收获,也希望笔者的小文让你们读起来没有那么晦涩,幸会。
关于ADT的一些简单解释及理解相关推荐
- javascript迭代器_JavaScript符号,迭代器,生成器,异步/等待和异步迭代器-全部简单解释...
javascript迭代器 by rajaraodv 通过rajaraodv JavaScript符号,迭代器,生成器,异步/等待和异步迭代器-全部简单解释 (JavaScript Symbols, ...
- Lucene的评分(score)机制的简单解释
Lucene的评分(score)机制的简单解释 博客分类: Lucene lucene编程Apachethread 通过Searcher.explain(Query query, int do ...
- 常用CSS元素div ul dl dt ol的简单解释
几个css元素的简单解释 div ul dl dt oldiv,这个很常见,块级元素,div尽量少用,和table一样,嵌套越少越好 ol 有序列表. <ol> <li>--& ...
- 如何用最简单的方式理解傅立叶变换?
你还在因为傅立叶挂科而头疼不已吗? 傅立叶变换经常被称为大学的杀手课程,傅立叶变换不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式. 但不幸的是,傅立叶变换的公式看起来太复杂了,所 ...
- 广度优先遍历类似于二叉树的_二叉树的各种遍历方法的简单解释
二叉树顾名思义,最多两个孩子. 一般规定一个二叉树,因为节点间有相互连接的原因,所以只要给定根节点,那么顺着寻找左孩子和右孩子便可以遍历到所有的节点,这就是遍历的直观解释. 而遍历分为深度遍历和广度遍 ...
- 简单解释什么是 依赖注入 和 控制反转
简单解释什么是 依赖注入 和 控制反转 2017-07-09 关于 依赖注入 与 控制反转 的概念有些人觉得很难理解,最近在给别人讲这个概念的时候梳理了一个比较好理解的解释,而且我认为非技术人员也应该 ...
- resultset不支持循环遍历_二叉树的各种遍历方法的简单解释
二叉树顾名思义,最多两个孩子. 一般规定一个二叉树,因为节点间有相互连接的原因,所以只要给定根节点,那么顺着寻找左孩子和右孩子便可以遍历到所有的节点,这就是遍历的直观解释. 而遍历分为深度遍历和广度遍 ...
- 教ai玩游戏_简单解释:DeepMind如何教AI玩视频游戏
教ai玩游戏 by Aman Agarwal 通过阿曼·阿加瓦尔(Aman Agarwal) 简单解释:DeepMind如何教AI玩视频游戏 (Explained Simply: How DeepMi ...
- iOS学习重要知识点整理02-进程和线程的一个简单解释
http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 阮一峰的网络日志 » 首页 » 档案 上一篇:熵的社会学意义 下一篇 ...
最新文章
- 软件熵:软件开发中推倒重来的过程就是软件熵不断增加的过程
- iOS上获取iTunes音乐权限
- ODBC的多线程应用
- 45页的NAS神经网络搜索的综述,请查收!
- java jooq_将Java EE与jOOQ结合使用的初学者指南
- 数学的记号(notation)
- 记一次使用Openssl生成p12证书搭建https证书
- 旅游出行 APP 哪家强?
- 英语二 - 常用词根二
- 笔记本当服务器显示器怎么连接,笔记本当主机显示器的设置方法
- 张小龙4个小时演讲全文:每天有1亿人教我做产品(下)
- Mac配置docker镜像源
- Android 文字的收起与展开功能
- sql文件反向生成物理概念模型
- 健身之徒手健身:双人徒手健身,这才是男女搭配最好追求!
- java常规普氏分析法,python AI换脸 用普氏分析法(Procrustes Analysis)实现人脸对齐...
- python 乘法运算定律_乘法运算定律专项练习题整理
- 基于51单片机的停车场车位管理系统
- Gaea To Houdini
- 鸿蒙是另一种安卓吗,鸿蒙不是另一个安卓或者iOS!鸿蒙2.0上线倒计时
热门文章
- HER2靶向药物研发进展-销售数据-上市药品前景分析
- android rtp 开源,关于开源的RTP
- 站长必须知道的seo知识!
- 防患于未“燃”的智能水气表解决方案,你心动了吗?
- 2016全球与中国市场智能煤气表深度研究报告
- unet和mask rcnn
- 想入行新媒体运营,到底都需要做哪些准备?
- 从零开始的JavaScript入门-使用JS绘制柱状图与折线图
- 错误信息:FATAL: No bootable medium found! System halted.
- PostgreSQL 实时位置跟踪+轨迹分析系统实践 - 单机顶千亿轨迹/天