1 / 22

第二章 抽象数据类型和 C++ 类

第二章 抽象数据类型和 C++ 类. 抽象数据类型 (Abstract Data Type,ADT) 是 用户 在基本数据类型基础上定义和实现的数据类型。 一种抽象数据类型就是定义了一种新的 数据元素集合 和该数据元素集合上所允许的 操作集合 。 抽象数据类型在更高一级的抽象程度上实现了信息的 隐藏 和 封装 。 C++ 中类的定义体现了抽象数据类型的 思想 。 C++ 中对于面向对象程序设计的支持 , 核心部分就是 类 的定义。. 2.1 抽象数据类型. 2.1.1 从数据类型到抽象数据类型

jada
Download Presentation

第二章 抽象数据类型和 C++ 类

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第二章 抽象数据类型和C++类 • 抽象数据类型(Abstract Data Type,ADT)是用户在基本数据类型基础上定义和实现的数据类型。 • 一种抽象数据类型就是定义了一种新的数据元素集合和该数据元素集合上所允许的操作集合。 • 抽象数据类型在更高一级的抽象程度上实现了信息的隐藏和封装。 • C++中类的定义体现了抽象数据类型的思想。C++中对于面向对象程序设计的支持,核心部分就是类的定义。

  2. 2.1 抽象数据类型 2.1.1 从数据类型到抽象数据类型 • 数据类型定义:一组性质相同的值的集合, 以及定义于这个值集合上的一组操作的总称. • C语言中的基本数据类型有 char int float double void 字符型 整型 浮点型 双精度型 无值

  3. 数据类型规定了其值的集合中元素的取值范围和对这些元素所能采用的操作。数据类型规定了其值的集合中元素的取值范围和对这些元素所能采用的操作。 例如: 整型定义了其数据集合中的元素的: 可取的值是机器所能表示的最小负整数和最大正整数之间的任何一个整数。 可用的操作有单目运算符+、-,双目运算符+、-、*、/、%,关系运算符<、<=、>、>=、==、!=和赋值运算符=等。 而抽象数据类型:

  4. 抽象数据类型 定义:是用户自己定义和实现的数据类型。 是指一个数学模型以及定义在该模型上的一组操作。 是用以表示应用问题的数据模型,由基本的数据类型组成,并包括一组相关的服务(或称操作)。 抽象数据类型类似于在计算机机器语言的“位、字节和字”的基础上引入“字符、整数、浮点数和双精度数”等数据类型这样一种方法。 这里,“字符、整数、浮点数和双精度数”等数据类型是对“位、字节和字”的抽象。

  5. 因为计算机是使用二进制定点数和浮点数来实现数据的存储和运算的。因为计算机是使用二进制定点数和浮点数来实现数据的存储和运算的。 从计算机硬件系统的角度看,计算机能处理的数据类型只包括位、字节和字。 高级程序设计语言中引入了字符、整数、浮点数、双精度数后,程序中就可以直接使用“A”,“57”,“1.3E10”等数据表示,而不必使用它们的二进制表示。 编译程序会将这些数据值转换成二进制码。 这些数据表示就是二进制数据的抽象。

  6. 一个抽象数据类型定义了一种新的数据元素集合和数据元素集合上所允许的操作集合。一个抽象数据类型定义了一种新的数据元素集合和数据元素集合上所允许的操作集合。 在高级程序设计语言中,由基本数据类型可以定义出更高一级的抽象数据类型,如各种表、队列、图甚至窗口、管理器等。 下面以“队列”为例,解释抽象数据类型。 一个队列是由若干个元素组成的一个序列以及这个序列上的相关操作所构成。 其操作遵循的是“先到先服务”的原则。 当新的元素进队列:加入在队列的尾部。 当元素出队列:总是取出队列头的元素。

  7. 队列中的元素可以是各种不同类型的对象。它们可以是整数,也可以是字符,也可以是字符串,甚至可以是关于一个学生的记录。队列中的元素可以是各种不同类型的对象。它们可以是整数,也可以是字符,也可以是字符串,甚至可以是关于一个学生的记录。 不管是由什么对象组成队列,都不影响我们对“队列”本质的理解。 “队列”本质就是“先进先出”。 所以,可把队列看成是一个抽象数据类型。

  8. 注意:对于一个其数据成员完全相同的数据类型,如果对它作不同的“限制”,即定义不同功能的一组操作,就可以形成不同的抽象数据类型。如栈和队列,可能都是相同的顺序表结构,但“限制”不同,则具有不同的服务,因此是不同的抽象数据类型。注意:对于一个其数据成员完全相同的数据类型,如果对它作不同的“限制”,即定义不同功能的一组操作,就可以形成不同的抽象数据类型。如栈和队列,可能都是相同的顺序表结构,但“限制”不同,则具有不同的服务,因此是不同的抽象数据类型。 抽象数据类型与具体应用无关,这样我们在编程序的时候就可以把注意力集中在数据及其操作的理想模型上。 如何描述抽象数据类型?

  9. 2.1.2 抽象数据类型描述 抽象数据类型的特征是把使用和实现分离开来,实行封装和信息隐藏。 每种抽象数据类型的描述应包括: • 抽象数据类型的名(称) • 数据集合的定义 • 每种操作的名称,该操作的输入、前置条件、功能、输出和后置条件等定义。 一个抽象数据类型的描述在形式上可繁可简,描述形式举例如下:

  10. ADT抽象数据类型名is Data 数据元素集合和数据元素间的关系 Operation 构造函数 数据值的初始化 操作1 输 入:用户输入的数据值 前置条件:执行此操作前数据所必需的状态 动 作:对数据进行的处理 输 出:操作后的返回值描述 后置条件:系统执行操作后数据的状态 操作2 …… 操作3 …… endADT抽象数据类型名

  11. 例2-1要设计一个掷骰子( zhìtóuzi)的程序,骰子可设计成一个抽象数据类型Dice. 其数据类型包括:被掷骰子个数N, 掷出骰子的总点数, 每个骰子的点数; 其操作包括: 掷骰子, 返回该次投掷的骰子总点数, 打印所掷每个骰子的点数。 ADT Dice is Data//数据集合 该次投掷骰子的个数。这是一个大于或等于1的整数。 该次掷出的总点数。这是一个大于等于N且小于等于6N的整数。 该次掷出的每个骰子的点数。这是一个表,表中的数值均为1到6的整数。

  12. Operation//操作 Constructor 构造函数 确定被投掷骰子的个数 Toss //掷骰子 输入:无 前置条件:无 动作:掷骰子并计算总点数 输出:无 后置条件:投掷的总点数及每个骰子的点数 Total //总点数 输入:无 前置条件:无 动作:检索该次投掷的总点数数据项 输出:返回该次投掷的总点数 后置条件:无 DisplayToss //各骰子的点数 输入:无 前置条件:无 动作:打印该次投掷的各骰子的点数 输出:无 后置条件:无 endADT Dice

  13. 本章的其他内容,同学们在上学期已经学过,这里就不再重复。但请同学们注意复习,特别是有关模板的内容。本章的其他内容,同学们在上学期已经学过,这里就不再重复。但请同学们注意复习,特别是有关模板的内容。

  14. template<class type> //模板声明 type max(type a,type b) //定义模板 {return(a>b)?a,b;} //函数模板说明 //函数模板的一般说明形式如下: template < 模板形参表> <返回值类型> <函数名>(模板函数形参表) { //函数定义体 } 上例: template<class type> //模板声明,class是关键字,type是模板形参名 type max(type a,type b) //定义模板,max前面的type是max函数的返回值类型,这里函数形参a和b的类型type就是<class type>中的type。但函数形参a和b的类型不一定就是type,也可以是其他标识符 {return(a>b)?a,b;} //定义函数体

  15. //类模板说明的一般形式是: template <类型形参表> //这里的“类型”是“可参数化”的 class <类名> { //类说明体 }; template <类型形参表> <返回类型> <类名> <类型形参名表>::<成员函数1>(形参表) { //成员函数定义体 } template <类型形参表> <返回类型> <类名> <类型形参名表>::<成员函数2>(形参表) { //成员函数定义体 } … template <类型形参表> <返回类型> <类名> <类型形参名表>::<成员函数n>(形参表) { //成员函数定义体 }

  16. elemttype是 类型形参 pair是 类名 例2-10交换两个变量x和y当前值 // 建立pair.h 文件 #ifndef PAIR_H #define PAIR_H template <class elemttype> class pair { public: void swap(elemttype *, elemttype *); void printpair(elemttype, elemttype); }; #endif //类说明体

  17. // 建立pair.cpp 文件 #include <iostream.h> #include "pair.h" template <class elemttype> void pair<elemttype>::swap(elemttype * firstelem, elemttype * secondelem) // pair<elemttype>是一个模板类 { elemttype temp; temp = *firstelem; *firstelem = *secondelem; *secondelem = temp; return; } template <类型形参表> <返回类型> <类名> <类型形参名表>::<成员函数1>(形参表) { //成员函数定义体 }

  18. template <class elemttype> void pair<elemttype>::printpair(elemttype firstelem, elemttype secondelem) { cout << "pair and swap for elemttyp\n"; cout << "first elemttype is " << firstelem; cout << "\nsecond elemttype is " << secondelem << "\n"; return; } template <类型形参表> <返回类型> <类名> <类型形参名表>::<成员函数1>(形参表) { //成员函数定义体 }

  19. template <class elemttype> void pair<elemttype>::printpair(elemttype firstelem, elemttype secondelem) { cout << "pair and swap for elemttyp\n"; cout << "first elemttype is " << firstelem; cout << "\nsecond elemttype is " << secondelem << "\n"; return; } int main() { pair<int> intpair; int firi, seci; firi = 99; seci = 77; intpair.printpair(firi, seci); intpair.swap(&firi, &seci); //&是取地址 intpair.printpair(firi, seci); pair<double> floatpair; double firf, secf; firf = 23.45; secf = 9.9; floatpair.printpair(firf, secf); floatpair.swap(&firf, &secf); floatpair.printpair(firf, secf); template <class elemttype> void pair<elemttype>::swap(elemttype * firstelem, elemttype * secondelem) // pair<elemttype>是一个模板类 { elemttype temp; temp = *firstelem; *firstelem = *secondelem; *secondelem = temp; return; }

  20. template <class elemttype> void pair<elemttype>::printpair(elemttype firstelem, elemttype secondelem) { cout << "pair and swap for elemttyp\n"; cout << "first elemttype is " << firstelem; cout << "\nsecond elemttype is " << secondelem << "\n"; return; } pair<char> charpair; char firc='w'; char secc = 'm'; charpair.printpair(firc, secc); charpair.swap(&firc, &secc); charpair.printpair(firc, secc); return 0; } 运行结果: pair and swap for elemttypfirst elemttype is 99second elemttype is 77pair and swap for elemttypfirst elemttype is 77second elemttype is 99

  21. template <class elemttype> void pair<elemttype>::printpair(elemttype firstelem, elemttype secondelem) { cout << "pair and swap for elemttyp\n"; cout << "first elemttype is " << firstelem; cout << "\nsecond elemttype is " << secondelem << "\n"; return; } pair and swap for elemttypfirst elemttype is 23.45second elemttype is 9.9pair and swap for elemttypfirst elemttype is 9.9second elemttype is 23.45pair and swap for elemttypfirst elemttype is wsecond elemttype is mpair and swap for elemttypfirst elemttype is msecond elemttype is w 模板类是抽象数据类型和重用的直接体现,在定义的时候,不必考虑其数据的具体类型。事实上,不论进行“交换”的数据类型是什么,都不影响我们对交换两个对象的值的理解。当用户需要交换两个具体类型的对象值的时候,只要将具体的类型例示即可。

  22. 谢谢!

More Related