您的位置:

抽象数据类型和python类(python的抽象类)

本文目录一览:

抽象数据类型

类的基础:抽象数据类型抽象数据类型(ADT, abstract data type)是指一些数据以及对这些数据所进行的操作的集合。这些操作既向程序的其余部分描述了这些数据是怎么样的,也允许程序的其余部分改变这些数据。“抽象数据类型”概念中“数据”一词的用法有些随意。一个ADT可能是一个图形窗体以及所有能影响该窗体的操作;也可以是一个文件以及对这个文件进行的操作;或者是一张保险费率表以及相关操作等等。要想理解面向对象编程,首先要理解ADT。不懂ADT的程序员开发出来的类只是名义上的“类”而已——实际上这种“类”只不过就是把一些稍有点儿关系的数据和子程序堆在一起。然而在理解ADT之后,程序员就能写出在一开始很容易实现、日后也易于修改的类来。传统的编程教科书在讲到抽象数据类型时,总会用一些数学中的事情打岔。这些书往往会像这么写:“你可以把抽象数据类型想成一个定义有一组操作的数学模型。”这种书会给人一种感觉,好像你从不会真正用到抽象数据类型似的——除非拿它来催眠。把抽象数据类型解释得这么空洞是完全丢了重点。抽象数据类型可以让你像在现实世界中一样操作实体,而不必在低层的实现上摆弄实体,这多令人兴奋啊。你不用再向链表中插入一个节点了,而是可以在电子表格中添加一个数据单元格,或向一组窗体类型中添加一个新类型,或给火车模型加挂一节车厢。深入挖掘能在问题领域工作(而非在底层实现领域工作)的能量吧!Example of the Need for an ADT需要用到ADT的例子为了展开讨论,这里先举一个例子,看看ADT在什么情况下会非常有用。有了例子之后我们将继续深入细节探讨。假设你正在写一个程序,它能用不同的字体、字号和文字属性(如粗体、斜体等)来控制显示在屏幕上的文本。程序的一部分功能是控制文本的字体。如果你用一个ADT,你就能有捆绑在相关数据上的一组操作字体的子程序——有关的数据包括字体名称、字号和文字属性等。这些子程序和数据集合为一体,就是一个ADT。如果不使用ADT,你就只能用一种拼凑的方法来操纵字体了。举例来说,如果你要把字体大小改为12磅(point),即高度碰巧为16个像素(pixel),你就要写类似这样的代码:currentFont.size = 16如果你已经开发了一套子程序库,那么代码可能会稍微好看一些:currentFont.size = PointsToPixels(12)或者你还可以给该属性起一个更特定的名字,比如说:currentFont.sizeOnPixels = PointsToPixels(12)但你是不能同时使用currentFont.sizeInPixels和currentFont.sizeInPoints,因为如果同时使用这两项数据成员,currentFont就无从判断到底该用哪一个了。而且,如果你在程序的很多地方都需要修改字体的大小,那么这类语句就会散布在整个程序之中。如果你需要把字体设为粗体,你或许会写出下面的语句,这里用到了一个逻辑or运算符和一个16进制常量0x02:currentFont.attribute = CurrentFont.attribute or 0x02如果你够幸运的话,也可能代码会比这样还要干净些。但使用拼凑方法的话,你能得到的最好结果也就是写成这样:currentFont.attribute = CurrentFont.attribute or BOLD或者是这样:currentFont.bold = True就修改字体大小而言,这些做法都存在一个限制,即要求调用方代码直接控制数据成员,这无疑限制了currentFont的使用。如果你这么编写程序的话,程序中的很多地方就会到处充斥着类似的代码。Benefits of Using ADTs使用ADT的益处问题并不在于拼凑法是种不好的编程习惯。而是说你可以采用一种更好的编程方法来替代这种方法,从而获得下面这些好处:可以隐藏实现细节 把关于字体数据类型的信息隐藏起来,意味着如果数据类型发生改变,你只需在一处修改而不会影响到整个程序。例如,除非你把实现细节隐藏在一个ADT中,否则当你需要把字体类型从粗体的第一种表示变成第二种表示时,就不可避免地要更改程序中所有设置粗体字体的语句,而不能仅在一处进行修改。把信息隐藏起来能保护程序的其余部分不受影响。即使你想把在内存里存储的数据改为在外存里存储,或者你想把所有操作字体的子程序用另一种语言重写,也都不会影响程序的其余部分。

改动不会影响到整个程序 如果想让字体更丰富,而且能支持更多操作(例如变成小型大写字母、变成上标、添加删除线等)时,你只需在程序的一处进行修改即可。这一改动也不会影响到程序的其余部分。让接口能提供更多信息 像currentFont.size = 16这样的语句是不够明确的,因为此处16的单位既可能是像素也可能是磅。语句所处的上下文环境并不能告诉你到底是哪一种单位。把所有相似的操作都集中到一个ADT里,就可以让你基于磅数或像素数来定义整个接口,或者把二者明确地区分开,从而有助于避免混淆。更容易提高性能 如果你想提高操作字体时的性能,就可以重新编写出一些更好的子程序,而不用来回修改整个程序。让程序的正确性更显而易见 验证像currentFont.attribute = current-

Font.attribute or 0x02这样的语句是否正确是很枯燥的,你可以替换成像currentFont.SetBoldOn()这样的语句,验证它是否正确就会更容易一些。对于前者,你可能会写错结构体或数据项的名字,或者用错运算符(用了and而不是or),也可能会写错数值(写成了0x20而不是0x02)。但对于后者,在调用current-

Font.SetBoldOn()时,唯一可能出错的地方就是写错方法(成员函数)名字,因此识别它是否正确就更容易一些。程序更具自我说明性 你可以改进像currentFont.attribute or 0x02这样的语句——把0x02换成BOLD或“0x02所代表的具体含义”,但无论怎样修改,其可读性都不如currentFont.SetBoldOn()这条语句。Woodfield、Dunsmore和Shen曾做过这样一项研究,他们让一些计算机科学专业的研究生和高年级本科生回答关于两个程序的问题:第一个程序按功能分解为8个子程序,而第二个程序分解为抽象数据类型中的8个子程序(1981)。结果,按那些使用抽象数据类型程序的学生的得分比使用按功能划分的程序的学生高出超过30%。无须在程序内到处传递数据 在刚才那个例子里,你必须直接修改current-

Font的值,或把它传给每一个要操作字体的子程序。如果你使用了抽象数据类型,那么就不用再在程序里到处传递currentFont了,也无须把它变成全局数据。ADT中可以用一个结构体来保存currentFont的数据,而只有ADT里的子程序才能直接访问这些数据。ADT之外的子程序则不必再关心这些数据。你可以像在现实世界中那样操作实体,而不用在底层实现上操作它 你可以定义一些针对字体的操作,这样,程序的绝大部分就能完全以“真实世界中的字体”这个概念来操作,而不再用数组访问、结构体定义、True与False等这些底层的实现概念了。这样一来,为了定义一个抽象数据类型,你只需定义一些用来控制字体的子程序——多半就像这样:currentFont.SetSizeInPoints(sizeInPoints)currentFont.SetSizeInPixels(sizeInPixels)currentFont.SetGBoldOn()currentFont.SetBoldOff()currentFont.SetItalicOn()currentFont.SetItalicOff()currentFont.SetTypeFace(faceName)这些子程序里的代码可能很短——很可能就像你此前看到的那个用拼凑法控制字体时所写的代码。这里的区别在于,你已经把对字体的操作都隔离到一组子程序里了。这样就为需要操作字体的其他部分程序提供了更好的抽象层,同时它也可以在针对字体的操作发生变化时提供一层保护。

在数据结构里,什么是抽象数据类型

1、象数据类型(Abstract Data Type 简称ADT)是指一个数学模型以及定义在此数学模型上的一组操作。

2、抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。

3、抽象数据类型是与表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。

4、对一个抽象数据类型进行定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本数据类型那样,十分方便地使用抽象数据类型。

计算机语言中数据类型具体包括哪些

数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作。变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。在声明变量时也可指定它的数据类型。所有变量都具有数据类型,以决定能够存储哪种数据。

数据类型包括原始类型、多元组、记录单元、代数数据类型、抽象数据类型、参考类型以及函数类型。

求《数据结构与算法Python语言描述》全文免费下载百度网盘资源,谢谢~

《数据结构与算法Python语言描述》百度网盘pdf最新全集下载:

链接:

?pwd=jdjq 提取码: jdjq

简介:数据结构与算法Python语言描述基于Python语言介绍了数据结构与算法的基本知识,主要内容包括抽象数据类型和Python面向对象程序设计、线性表、字符串、栈和队列、二叉树和树、集合、排序以及算法的基本知识。本书延续问题求解的思路,从解决问题的目标来组织教学内容,注重理论与实践的并用。  

什么是抽象数据类型?

抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。

比如说类 就是 一种抽象数据类型,类是由已有的数据类型 来实现的。

如复数类型:

//在头文件complex.h中定义的复数类

#ifndef _complex_h_

#define _complex_h_

#include iostream.h

class complex {

public:

complex ( ){ Re = Im = 0; } //不带参数的构造函数

complex ( double r ) { Re = r; Im = 0; } //只置实部的构造函数

complex ( double r, double i ) { Re = r; Im = i; } //分别置实部、虚部的构造函数

double getReal ( ) { return Re; } //取复数实部

double getImag ( ) { return Im; } //取复数虚部

void setReal ( double r ) { Re = r; } //修改复数实部

void setImag ( double i ) { Im = i; } //修改复数虚部

complex operator = ( complex ob) { Re = ob.Re; Im = ob.Im; } //复数赋值

complex operator + ( complex ob ); //重载函数:复数四则运算

complex operator – ( complex ob );

complex operator * ( complex ob );

complex operator / ( complex ob );

friend ostream operator ( ostream os, complex c ); //友元函数:重载

private:

double Re, Im; //复数的实部与虚部

};

#endif

//复数类complex的相关服务的实现放在C++源文件complex.cpp中

#include iostream.h

#include math.h

#include “complex.h”

complex complex :: operator + ( complex ob ) {

//重载函数:复数加法运算。

complex * result = new complex ( Re + ob.Re, Im + ob.Im );

return *result;

}

complex complex :: operator – ( complex ob ) {

//重载函数:复数减法运算

complex * result = new complex ( Re – ob.Re, Im – ob.Im );

return * result;

}

complex complex :: operator * ( complex ob ) {

//重载函数:复数乘法运算

complex * result =

new complex ( Re * ob.Re – Im * ob.Im, Im * ob.Re + Re * ob.Im );

return *result;

}

complex complex :: operator / ( complex ) {

//重载函数:复数除法运算

double d = ob.Re * ob.Re + ob.Im * ob.Im;

complex * result = new complex ( ( Re * ob.Re + Im * ob.Im ) / d,

( Im * ob. Re – Re * ob.Im ) / d );

return * result;

}

friend ostream operator ( ostream os, complex ob ) {

//友元函数:重载,将复数ob输出到输出流对象os中。

return os ob.Re ( ob.Im = 0.0 ) ? “+” : “-” fabs ( ob.Im ) “i”;

}