实验二 抽象数据类型的表 示和实现
数据结构8个实验项目

一、【实验目的】 1、掌握串的顺序定长存储结构的类型定义方法。 2、掌握串的堆分配存储结构的类型定义方法。 3、理解串的基本模式匹配算法。 二、【实验内容】 【基础篇】: 1、利用串的顺序定长存储结构实现两个子串的连接。 要求:两个子串从键盘输入获得;从屏幕显示连接后的新串元素列表。 将源程序以实验 4-1 为文件名保存在自己的文件夹里面。 2、利用串的堆配存储结构实现两个子串的连接。 【提高篇】: 2、上机实现朴素的串匹配算法。要求: 从键盘输入主串和 子串元素, 调用朴素的串 匹配算法,判 断子串是否 在主串中,若 在, 返回起始位置,否则显示否定信息。
1
设计 必做 存储结构上的实现
计算机
3 栈和队列及其应用 4
深入了解栈和队列的特性,以便在实
1
设计 必做 际问题背景下灵活运用
计算机
4 串及其应用
熟 悉 串 类 型的 实 现方 法 和 文本 模 式
4
1
设计 必做 匹配方法
计算机
矩阵的 压缩存 储应
5
(4)
用
深 入 研 究 数组 的 存储 表 示 和实 现 技
实验一 抽象数据类型实现方法
一、【实验目的】 1、理解和掌握 ADT 实现方法。 2、掌握 ADT 三元组或者复数类的实现方法。 3、熟悉 VC6.0 或者 C++编程环境 二、【实验内容】 1、实验前,在 D 盘建立一个文件夹(文件夹名称用自己的班级加姓名命名),将源程序 以实验 1-1 为文件名保存在自己的文件夹里面。 【基础篇】: 2、建立三元组抽象数据类型定义的头文件,编程实现三元组的基本操作,输出任意三元 组的最大值和最小值。 【提高篇】:
1 设计 必做
计算机
术,熟悉广义表的存储结构的特性
2抽象数据类型的表示与实现算法

9
9. 注释 // , /* …… */
10.基本函数
max, min, abs, eof, eoln
11. 逻辑运算约定
&&:A&&B A为0时 ,不再对B求值 ||:A||B A为非0时,不再对B求值
12. 结构体 struct 结构体类型名{ 成员说明列表 }; struct student{ int num; char name[20]; int age; }; struct student stu1;
算法的描述:本书中使用类C语言。 一个算法必须满足以下五个重要特性:
1)有穷性 2)确定性 3)可行性
4)输入 5)输出
16
1)有穷性 对于任意一组合法输入值,在 执行有穷步骤之后一定能结束,即: 算法中的每个步骤都能在有限时间内完成。 2)确定性 算法中每条指令必须有确切的含 义,读者理解时不会产生二义性,并且在任 何条件下,算法都只有唯一的一条执行路径, 即对于相同的输入只能得出相同的输出。
c.程序对于精心选择的、典型、苛刻且带有刁难性的几组 输入数据能够得出满足要求的结果;
一般情况下,通常以第c层意义的正确性作为衡量一个程 序是否合格的标准。
d.程序对于一切合法的输入数据都能得出满足要求的结果。
2)可读性
21
算法主要是为了人的阅读与交流, 其次才是为计算机执行,因此算法应该 易于人的理解;另一方面,晦涩难读的 程序易于隐藏较多错误而难以调试。
一般,算法的时间复杂度如无特别说明 ,则指最坏情况下的时间复杂度。
4、算法的存储空间需求
33
算法的空间复杂度定义为:
广义表实验报告

⼴义表实验报告抽象数据类型的实现1.实验概要实验项⽬名称: 抽象数据类型的实现实验项⽬性质: 设计性实验所属课程名称: 数据结构实验计划学时: 62.实验⽬的对某个具体的抽象数据类型,运⽤课程所学的知识和⽅法,设计合理的数据结构,并在此基础上实现该抽象数据类型的全部基本操作。
通过本设计性实验,检验所学知识和能⼒,发现学习中存在的问题。
进⽽达到熟练地运⽤本课程中的基础知识及技术的⽬的。
3.编译软件Microsoft Visual C++6.04.抽象数据类型定义以及各基本操作的简要描述ADT GList{数据对象:D={i=1,2,...,n>=0;ei (-AtomSet或ei (-GList,AtomSet为某个数据对象} 数据关系:R1={|ei-1,ei (-D,2=基本操作:InitGlist(&L);操作结果:创建空的⼴义表LCreateGList(&L,S);初始条件:S是⼴义表的书写形式串操作结果:由S创建⼴义表LDestroyGlist(&L);初始条件:⼴义表L存在操作结果:销毁⼴义表LCopyGlist(&T,L);初始条件:⼴义表L存在操作结果:由⼴义表L复制得到⼴义表TGListLength(L);初始条件:⼴义表L存在操作结果:求⼴义表L的长度,即元素个数GListDepth(L);初始条件:⼴义表L存在初始条件:⼴义表L存在操作结果:判断⼴义表L是否为空GetHead(L);初始条件:⼴义表L存在操作结果:取⼴义表L的头GList GetTail(L)初始条件:⼴义表L存在操作结果: 取⼴义表L的尾InsertFirst_GL(&L,e)初始条件:⼴义表L存在操作结果:插⼊元素e作为⼴义表L的第⼀元素DeleteFirst_GL(GList &L,&e)初始条件:⼴义表L存在操作结果:删除⼴义表L的第⼀元素,并⽤e返回其值Traverse_GL(GList L,void(*v)(AtomType))初始条件:⼴义表L存在操作结果:遍历⼴义表L,⽤函数Visit处理每个元素} ADT GList5.⼴义表的存储结构-------⼴义表的扩展线性链表存储表⽰------typedef enum{ATOM,LIST}ElemTag; // ATOM==0:原⼦,LIST==1:⼦表typedef struct GLNode{ElemTag tag; // 公共部分,⽤于区分原⼦结点和表结点union // 原⼦结点和表结点的联合部分{AtomType atom; // 原⼦结点的值域struct GLNode *hp; // 表结点的表头指针}a;struct GLNode *tp; // 相当于线性链表的next,指向下⼀个元素结点 }*GList,GLNode;6.主函数及部分函数流程图主函数流程图:由S创建⼴义表L流程图:销毁⼴义表L流程图:求⼴义表L深度流程图:⼴义表L长度流程图:遍历⼴义表L流程图:7.程序清单#include /头⽂件a.h/#include#include#include#include#define TRUE 1 / 函数结果状态代码/ #define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef char AtomType;typedef int Status;typedef struct / 串的堆分配存储/{char *ch;int length;}HString;typedef enum{ATOM,LIST}ElemTag; /⼴义表的扩展线性链表存储表⽰/ typedef struct GLNode {ElemTag tag;union{AtomType atom;struct GLNode *tp;}*GList,GLNode;void InitString(HString *T); /函数声明/int StrCompare(HString S,HString T);int StrLength(HString S);Status StrAssign(HString *T,char *chars);Status StrCopy(HString *T,HString S);Status StrEmpty(HString S);Status ClearString(HString *S);Status SubString(HString *Sub, HString S,int pos,int len); Status sever(HString *str,HString *hstr);GList GetHead(GList L);GList GetTail(GList L);void visit(AtomType e);void Traverse_GL(GList L,void(*v)(AtomType));int GListLength(GList L);int GListDepth(GList L);Status InitGList(GList *L);Status CreateGList(GList *L,HString S);Status DestroyGList(GList *L);Status CopyGList(GList *T,GList L);Status GListEmpty(GList L);Status InsertFirst_GL(GList *L,GList e);Status DeleteFirst_GL(GList *L,GList *e);Status StrAssign(HString *T,char *chars) /串的操作/ { /⽣成⼀个其值等于串常量chars的串T / int i,j;if((*T).ch)free((*T).ch); /释放T原有空间/i=strlen(chars);if(!i){(*T).ch=NULL;(*T).length=0;{(*T).ch=(char*)malloc(i*sizeof(char)); /分配串空间/ if(!(*T).ch)exit(OVERFLOW);for(j=0;j(*T).ch[j]=chars[j];(*T).length=i;}return OK;}Status StrCopy(HString *T,HString S){ /由串S复制得串T /int i;if((*T).ch)free((*T).ch); /释放T原有空间/(*T).ch=(char*)malloc(S.length*sizeof(char));if(!(*T).ch) /分配串空间失败/exit(OVERFLOW);for(i=0;i(*T).ch[i]=S.ch[i];(*T).length=S.length;return OK;}Status StrEmpty(HString S){ /若S为空串,则返回TRUE,否则返回FALSE /if(S.length==0&&S.ch==NULL)return TRUE;elsereturn FALSE;}int StrCompare(HString S,HString T){ /若S>T,则返回值>0;若S=T,则返回值=0;若Sfor(i=0;ireturn S.length-T.length;}int StrLength(HString S){ /返回S的元素个数,称为串的长度/return S.length;}Status ClearString(HString *S){ /清空串/if((*S).ch){free((*S).ch);(*S).ch=NULL;}(*S).length=0;return OK;}Status SubString(HString *Sub, HString S,int pos,int len) { /⽤Sub返回串S的第pos个字符起长度为len的⼦串/ int i; if(pos<1||pos>S.length||len<0||len>S.length-pos+1) return ERROR;if((*Sub).ch)free((*Sub).ch);if(!len) /空⼦串/{(*Sub).ch=NULL;(*Sub).length=0;}else / 完整⼦串/{(*Sub).ch=(char*)malloc(len*sizeof(char));if(!(*Sub).ch)exit(OVERFLOW);for(i=0;i<=len-1;i++)return OK;}void InitString(HString *T){ /产⽣空串/(*T).length=0;(*T).ch=NULL;}Status sever(HString *str,HString *hstr){ /将⾮空串str分割成两部分:hstr为第⼀个','之前的⼦串,str为之后的⼦串/ int n,i=1,k=0; HString ch,c1,c2,c3;InitString(&ch);InitString(&c1);InitString(&c2);InitString(&c3);StrAssign(&c1,",");StrAssign(&c2,"(");StrAssign(&c3,")");n=StrLength(*str);do{SubString(&ch,*str,i,1);if(!StrCompare(ch,c2))++k;else if(!StrCompare(ch,c3))--k;++i;}while(i<=n&&StrCompare(ch,c1)||k!=0);if(i<=n){StrCopy(&ch,*str);SubString(hstr,ch,1,i-2);SubString(str,ch,i,n-i+1);StrCopy(hstr,*str);ClearString(str);}return OK;}Status InitGList(GList *L) /⼴义表的操作/ { /创建空的⼴义表/*L=NULL;return OK;}Status CreateGList(GList *L,HString S) { /由S创建⼴义表/HString emp,sub,hsub;GList p;InitString(&emp);InitString(&sub);InitString(&hsub);StrAssign(&emp,"()");*L=(GList)malloc(sizeof(GLNode));if(!*L)exit(OVERFLOW);if(!StrCompare(S,emp)) /创建空表/{(*L)->tag=LIST;(*L)->a.hp=NULL;(*L)->tp=NULL;}else if(StrLength(S)==1) /创建单原⼦⼴义表/ {(*L)->tag=ATOM;(*L)->a.atom=S.ch[0];(*L)->tp=NULL;(*L)->tag=LIST;(*L)->tp=NULL;SubString(&sub,S,2,StrLength(S)-2); /脱外层括号/sever(&sub,&hsub); / 从sub中分离出表头串hsub / CreateGList(&(*L)->a.hp,hsub); p=(*L)->a.hp;while(!StrEmpty(sub)) /表尾不空,则重复建n个⼦表/{sever(&sub,&hsub);CreateGList(&p->tp,hsub);p=p->tp;};}return OK;}Status DestroyGList(GList *L){ /销毁⼴义表/GList ph,pt;if(*L) /L不为空表/{if((*L)->tag) /当L是⼦表/ph=(*L)->a.hp;else /当L是原⼦/ph=NULL;pt=(*L)->tp;free(*L); /释放L所指结点/*L=NULL;DestroyGList(&ph); /递归销毁表ph /DestroyGList(&pt); /递归销毁表pt /}return OK;}Status CopyGList(GList *T,GList L)*T=NULL;return OK;}*T=(GList)malloc(sizeof(GLNode));if(!*T)exit(OVERFLOW);(*T)->tag=L->tag;if(L->tag==ATOM) /复制共⽤体部分/(*T)->a.atom=L->a.atom; /复制单原⼦/ elseCopyGList(&(*T)->a.hp,L->a.hp); /复制⼦表/ if(L->tp==NULL)(*T)->tp=L->tp;elseCopyGList(&(*T)->tp,L->tp); /复制⼦表/ return OK;}int GListLength(GList L){ /求⼴义表L的长度/int len=0;GList p;if(L->tag==LIST&&!L->a.hp) /空表/return 0;else if(L->tag==ATOM) /单原⼦表/return 1;else /⼀般表/{p=L->a.hp;do{len++;p=p->tp;}while(p);}int GListDepth(GList L){ /求⼴义表L的深度/int max,dep;GList pp;if(L==NULL||L->tag==LIST&&!L->a.hp)return 1; /空表深度为1/else if(L->tag==ATOM)return 0; /单原⼦表深度为0 /else /求⼀般表的深度/for(max=0,pp=L->a.hp;pp;pp=pp->tp){dep=GListDepth(pp);if(dep>max)max=dep;}return max+1; /⾮空表的深度是各元素的深度的最⼤值加1 / } Status GListEmpty(GList L){ /判定⼴义表L是否为空/if(!L||L->tag==LIST&&!L->a.hp)return OK;elsereturn ERROR;}GList GetHead(GList L){ /取⼴义表表头/GList h;InitGList(&h);if(!L||L->tag==LIST&&!L->a.hp){printf("\n空表⽆表头!");exit(0);}exit(OVERFLOW);h->tag=L->a.hp->tag;h->tp=NULL;if(h->tag==ATOM)h->a.atom=L->a.hp->a.atom;elseCopyGList(&h->a.hp,L->a.hp->a.hp);return h;}GList GetTail(GList L){ /取⼴义表表尾/GList T;if(!L){printf("\n空表⽆表尾!");exit(0);}T=(GList)malloc(sizeof(GLNode));if(!T)exit(OVERFLOW);T->tag=LIST;T->tp=NULL;CopyGList(&T->a.hp,L->a.hp->tp);return T;}Status InsertFirst_GL(GList *L,GList e){ /插⼊元素e作为⼴义表L的第⼀元素/ GList p=(*L)->a.hp; (*L)->a.hp=e;e->tp=p;return OK;}Status DeleteFirst_GL(GList *L,GList *e){ /删除⼴义表L的第⼀元素,并⽤e返回其值/ if(*L)(*L)->a.hp=(*e)->tp;(*e)->tp=NULL;}else*e=*L;return OK;}void Traverse_GL(GList L,void(*v)(AtomType)) { /遍历⼴义表/GList hp;if(L){if(L->tag==ATOM) /L是原⼦/{v(L->a.atom);hp=NULL;}else /L是⼦表/hp=L->a.hp;Traverse_GL(hp,v);Traverse_GL(L->tp,v);}}void visit(AtomType e){printf("%c ", e);}void main() /主函数/{char p[80];GList l,m;HString t;InitString(&t);Status Eflag;int x;int d;do{E flag=TRUE;d o{system("cls");printf("\n***************************************************"); printf("\n1:建⽴空⼴义表");printf("\n2:由字符串建⽴⼴义表");printf("\n3:退出");printf("\n***************************************************"); printf("\n请选择功能:");scanf("%d",&x);switch(x){case 1: if(InitGList(&l)){printf("\n建表成功!");getch();}else{printf("\n建表失败!");getch();Eflag=FALSE;}break;case 2: printf("\n请输⼊合法的⼴义表书写形式"); printf("\n格式如:(),(a,b),(a,(),b),(a,(c,d),f)");printf("\n输⼊字符串:");if(CreateGList(&l,t)){printf("\n建表成功!");getch();}else{printf("\n建表失败!");getch();Eflag=FALSE;}break;case 3: printf("\n感谢使⽤本软件!");getch();exit(0);default: printf("\n输⼊错误!请重新输⼊!");getch();}}w hile(x!=1&&x!=2||!Eflag);d o{Status Eflag=TRUE;system("cls");printf("\n***************************************************"); printf("\n1:复制⼴义表");printf("\n2:求⼴义表长度");printf("\n3:求⼴义表深度");printf("\n4:判断⼴义表是不是空表");printf("\n5:取⼴义表表头");printf("\n6:取⼴义表表尾");printf("\n7:头结点插⼊元素");printf("\n8:删除第⼀个元素");printf("\n11:退出");printf("\n***************************************************"); printf("\n请选择功能:");printf("\n请输⼊你要选择的功能:");scanf("%d",&x);switch(x){case 1: if(CopyGList(&m,l)){printf("\n复制成功!");getch();}break;。
数据结构实验抽象数据类型——复数运算报告

【实验题目】实验1. 抽象数据类型. 【问题描述】用C 或C++语言设计并实现一个可进行复数运算的演示程序。
【基本要求】1.由输入的实部和虚部生成一个复数2.两个复数求和3.两个复数求差4.从已知复数中分离出实部和虚部5.复数及相应运算结果以相应的表现形式显示。
【实现提示】定义复数为由两个相互之间存在次序关系的实数构成的抽象数据类型,则可以利用实数的操作来实现复数的操作。
(下面的内容由学生填写,格式统一为,字体: 楷体, 行距: 固定行距18,字号: 小四) 一、【实验构思(Conceive )】(10%)(本部分应包括:描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计、算法等相关知识)1. 首先构造结构体数组接受储存数据2. 构造函数进行模块运算3. 应用到了算法中的抽象数据类型ADT (即数据+操作),数据部分包括实部和虚部;操作部分包括加分Plus 、减法Minus 、乘法Multiply 、除法Divide 4. 运用到了复数的基本知识及四则运算法则:设 z 1=a + bi ,z 2=c + di ,(a ,b ,c ,d ∈R ,)加减法:(a + bi )±(c + di )=(a ± c )+(b ± d )i 乘法:(a + bi )*(c + di )=(ac - bd )+(ad + bc )i除法: 2222()()()()a bi a bi c di ac bd bc ad ic di cd c d++-+-==+++ 二、【实验设计(Design)】(15%) (本部分应包括:抽象数据类型的功能规格说明、主程序模块、各子程序模块的伪码说明,主程序模块与各子程序模块间的调用关系) 解答:抽象数据类型 数据部分:用结构体(数组)实现复数的储存结构 操作部分:实现复数的输入、存储、运算及输出 程序模块伪码说明: #define N 2int n=0; //控制选择语句,及检验输入是否正确 typedef struct{double real;//复数的实部double imag;//复数的虚部}paramater; //paramater是结构体变量的类型表示“复数”,声明复数的存储结构paramater cpxNum[N];//构造结构体数组储存数据paramater result;//构造result结构体储存结果int main(){//实现第一个复数的输入储存cout<<"\t请输入第一个复数的实部和虚部:";cin>>real>>imag;outs(c[0].real,c[0].imag)//初始化复数c[0]并实现输出//实现第二个复数的输入储存cout<<"\t请输入第二个复数的实部和虚部:";cin>>real>>imag;puts( c[0].real,c[0].imag);//初始化复数c[1]并实现输出//复数运算cout << "c1 + c2的结果是: "; puts(plus(c[0],c[1])); cout << endl; //调用plus函数运算加法,再用puts函数输出结果复数cout << "c1 - c2的结果是: "; puts(milus(c[0],c[1])); cout << endl; //调用mlius函数运算减法,再用puts函数输出结果复数cout << "c1 * c2的结果是: "; puts(multiply(c[0],c[1])); cout << endl; //调用multiply函数运算乘法,再用puts函数输出结果复数cout << "c1 / c2的结果是: "; puts(divide(c[0],c[1])); cout << endl; //调用divide函数运算除法,再用puts函数输出结果复数return 0;}三、【实现描述(Implement)】(25%)(本部分应包括:抽象数据类型具体实现的函数原型说明、关键操作实现的伪码算法、函数设计、函数间的调用关系,关键的程序流程图等,给出关键算法的时间复杂度分析。
实验02抽象数据类型的表示及实现

浙江大学城市学院实验报告课程名称数据结构基础实验项目名称实验二抽象数据类型的表示和实现学生姓名专业班级学号实验成绩指导老师(签名)日期一.实验目的和要求1、通过抽象数据类型三元组的表示和实现,了解抽象数据类型的定义方式。
2、掌握抽象数据类型的定义方式和用C语言实现的方法。
3、熟悉如何运用主函数检验各基本操作函数的正确性的具体操作。
二.实验内容1、认真阅读以下有关抽象数据类型的知识:(1)抽象数据类型的概念抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。
抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关,即不论其内部结构如何变化,只要它的数学特性不变,就不影响其外部的使用。
一个含抽象数据类型的软件模块通常应包含定义、表示和实现3个部分。
抽象数据类型通常采用以下格式定义:ADT抽象数据类型名{数据对象:<数据对象的定义>数据关系:<数据关系的定义>基本操作:<基本操作的定义>} ADT抽象数据类型名(2)三元组的抽象数据类型定义及表示我们以抽象数据类型三元组为例,说明抽象数据类型是如何定义的。
三元组实际上就是一个数据对象中有3个数据元素。
三元组中元素的数据类型,可以是整型数,也可以是字符、浮点数或者更复杂的数据类型。
以下是三元组的抽象数据类型定义:ADT Triplet{数据对象:D={e1, e2, e3 | e1, e2, e3∈ElemSet (ElemSet为某个数据对象的集合)}数据关系:R1={<e1, e2>, <e2, e3>}基本操作:InitTriplet(&T, v1, v2, v3)操作结果:构造三元组T,元素e1, e2和e3分别被赋以v1, v2, v3值DestroyTriplet(&T)操作结果:三元组T被销毁Get(T, i, &e)初始条件:三元组T已存在,1≤i≤3操作结果:用e返回T的第i元的值IsAscending(T)初始条件:三元组T已存在操作结果:如果T的三个元素按升序排列,则返回1,否则返回0 IsDecending(Triplet T);初始条件: 三元组T已存在操作结果: 如果T的三个元素按降序排列,则返回1,否则返回0 Put(&T, i, e)初始条件:三元组T已存在,1≤i≤3操作结果:改变T的第i元的值为eMax(T, &e)初始条件:三元组T已存在操作结果:用e返回T的三个元素中的最大值Min(T, &e)初始条件:三元组T已存在操作结果:用e返回T的三个元素中的最小值} ADT Triplet三元组在计算机中的具体存储方式可以采用动态分配的顺序存储结构,如图所示:Triplet ElemType动态分配的顺序存储的三元组2、在计算机中实现上述三元组抽象数据类型。
实验一:抽象数据类型的表示与实现

(二〇一四年九月《数据结构》实验报告学校代码: 10128 学 号: 201220905048题 目:抽象数据类型的表示和实现 学生姓名:孙跃 学 院:理学院 系 别:数学系专 业:信息与计算科学 班 级:信计12-2 任课教师:杜雅娟一、实验目的1.熟悉Visual C++语言的上机环境,掌握C语言的基本结构。
2.理解抽象数据类型的表示和实现。
二、实验内容抽象数据类型Triplet的表示和实现。
三、实验程序根据给出的程序清单分别另建立4个文件:c1.h、c1-1.h、bo1-1.cpp和main1-1.cpp,并把它们保存在同一个文件夹中。
1.预定义常量和类型教材定义OK、ERROR等为函数结果状态代码,文件Status为其类型。
我们把这些信息放到头文件c1.h中。
c1.h还包含一些常用的,如string.h、stdio.h等。
为了操作的方便,几乎每一个程序都把c1.h包含进去,也就把这些结果状态代码和头文件包含了进去。
头文件的内容如下:// c1.h (程序名)#include<string.h>#include<ctype.h>#include<malloc.h> // malloc()等#include<limits.h> // INT_MAX等#include<stdio.h> // EOF(=^Z或F6),NULL#include<stdlib.h> // atoi()#include<io.h> // eof()#include<math.h> // floor(),ceil(),abs()#include<process.h> // exit()#include<iostream.h> // cout,cin// 函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE2.采用动态分配的顺序存储结构采用动态分配的顺序存储结构的头文件名取名为c1-1.h// c1-1.h 采用动态分配的顺序存储结构typedef ElemType *Triplet; // 由InitTriplet分配三个元素存储空间// Triplet类型是ElemType类型的指针类型,用它定义的变量存放ElemType类型数据的地址3.抽象数据类型Triplet和Elem Type的基本操作// bo1-1.cpp 抽象数据类型Triplet和ElemType(由c1-1.h定义)的基本操作(8个)Status InitTriplet(Triplet &T,ElemType v1,ElemType v2,ElemType v3){ // 操作结果:构造三元组T,依次置T的三个元素的初值为v1,v2和v3if(!(T=(ElemType *)malloc(3*sizeof(ElemType))))exit(OVERFLOW);T[0]=v1,T[1]=v2,T[2]=v3;return OK;}Status DestroyTriplet(Triplet &T){ // 操作结果:三元组T被销毁free(T);T=NULL;return OK;}Status Get(Triplet T,int i, ElemType &e){ // 初始条件:三元组T已存在,1≤i≤3。
抽象数据类型的表示与实现

抽象数据类型的表⽰与实现
抽象数据类型的表⽰与实现
抽象数据类型(Abstract Data Type 简称ADT)是指⼀个数学模型以及定义在此数学模型上的⼀组操作。
抽象数据类型需要通过固有数据类型(⾼级编程语⾔中已实现的数据类型)来实现。
抽象数据类型是与表⽰⽆关的数据类型,是⼀个数据模型及定义在该模型上的⼀组运算。
对⼀个抽象数据类型进⾏定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。
⼀旦定义了⼀个抽象数据类型及具体实现,程序设计中就可以像使⽤基本数据类型那样,⼗分⽅便地使⽤抽象数据类型。
抽象数据类型的描述包括给出抽象数据类型的名称、数据的集合、数据之间的关系和操作的集合等⽅⾯的描述。
【通俗的说:就是名字、数据集合、关系和操作的集合】
抽象数据类型描述的⼀般形式如下:
ADT抽象数据类型名称 {
数据对象:
……
数据关系:
……
操作集合:
操作名1:
……
……
操作名n:
}ADT抽象数据类型名称
总结:
抽象数据类型定义(ADT)
作⽤:抽象数据类型可以使我们更容易描述现实世界。
例:⽤线性表描述学⽣成绩表,⽤树或图描述遗传关系。
定义:⼀个数学模型以及定义在该模型上的⼀组操作。
关键:使⽤它的⼈可以只关⼼它的逻辑特征,不需要了解它的存储⽅式。
定义它的⼈同样不必要关⼼它如何存储。
例:线性表这样的抽象数据类型,其数学模型是:数据元素的集合,该集合内的元素有这样的关系:除第⼀个和最后⼀个外,每个元素有唯⼀的前趋和唯⼀的后继。
可以有这样⼀些操作:插⼊⼀个元素、删除⼀个元素等。
抽象数据类型如何表示和实现

2
f (n)
n
即f(n)≤log2n,取最大值f(n)=log2n
所以该程序段的时间复杂度T(n)=1+f(n)=1+ log2n= O( log2n)
3、抽象数据类型如何表示和实现? 抽象数据类型可以通过固有的数据类型(如整型、 实型、字符型等)来表示和实现。
注1 :它有些类似C语言中的结构(struct)类型, 但增加了相关的服务。
注2 :教材中用的是类C语言(介于伪码和C语言之 间)作为描述工具。 但上机时要用具体语言实现,如C或C++等
1.4 算法和算法分析
按书名
高等数学 001,003…… 理论力学 002,…….. 线性代数 004,…… …… ……..
樊映川 华罗庚 栾汝书 …….
按作者名
001,… 002,…. 004,…. …….
L S ……
按分类号
002,… 001,003, ……
索引表
例2
人机对奕问题
树
……..
……..
…...
…...
…...
算法评价有5个指标: 运行时间、占用空间、正确性、健壮性 和可读性
常用时间复杂度来衡量
常用空间复杂度来衡量
例:分析以下程序段的时间复杂度。
i=1; while(i<=n) i=i*2; ①
②
解: 该算法的运行时间由程序中所有语句的频度(即该语
句重复执行的次数)之和构成。
算法的时间复杂度是由嵌套最深层语句的频度决定的。
…...
1.2.2 基本概念及术语
什么是数据结构?
答: (见教材P6) 是相互之间存在一种或多种特 定关系的数据元素的集合,表示为:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
结果都正确
五. 心得体会 “&”的使用还需要多加练习
【附录----源程序】
test1_2.cpp: #include <iostream.h> #include <stdio.h> #include <stdlib.h> typedef int ElemType; typedef ElemType *Triplet; //定义动态分配的三元组类型, 指针Triplet #include "test1_2.h" void main() {
3、填写实验报告,实验报告文件取名为report2.doc。
4、上传实验报告文件report2.doc 、源程序文件test1_2.cpp及 test1_2.h到Ftp服务器上自己的文件夹下。
三 函数的功能说明及算法思路
int InitTriplet(Triplet &T, ElemType v1, ElemType v2, ElemType v3)
} ADT Triplet
三元组在计算机中的具体存储方式可以采用动态分配的顺序存储结 构,如图所示:
动态分配的顺序存储的三元组
2、 在计算机中实现上述三元组抽象数据类型。步骤如下: (1)首先搭好实现该抽象数据类型的整个C语言程序的模块框架结构
图,即在一个工程中分别建立两个文件:头文件test1_2.h与主程序文 件test1_2.cpp。 (2)编写test1_2.h和test1_2.cpp两个文件,其中test1_2.h中包含三 元组的各种操作函数的实现,test1_2.cpp中包含三元组存储结构定义 与主函数,主函数主要用于验证test1_2.h中各函数的正确性。编译并 调试程序,直到正确运行。
if(i>=1&&i<=3) e=T[i-1];
}
void IsAscending(Triplet T,int &i) {//初始条件:三元组T已存在;操作结果:如果T的三个元素按升序排 列,则返回1,否则返回0
if(T[0]<T[1]&&T[1]<T[2]) i=1;
else i=0; }
void IsDecending(Triplet T,int &i) {//初始条件: 三元组T已存在;操作结果: 如果T的三个元素按降序排列, 则返回1,否则返回0
if(T[i]<min) min=T[i];
e=min; }
2. 实验内容 1、 认真阅读以下有关抽象数据类型的知识: (1)抽象数据类型的概念
抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。 抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部 如何表示和实现无关,即不论其内部结构如何变化,只要它的数学特性 不变,就不影响其外部的使用。
Put(T, 1, 3); printf("将第一个值改为3后的三元组T的3个值为:%d, %d, %d\n", T[0], T[1], T[2]) ;
Put(T, 3, 1); printf("将第三个值改为1后的三元组T的3个值为:%d, %d, %d\n", T[0], T[1], T[2]) ;
if(T[0]>T[1]&&T[1]>T[2]) i=1;
else i=0; }
void Put(Triplet &T,int i,ElemType e) {//初始条件:三元组T已存在,1≤i≤3;操作结果:改变T的第i元的值为e
if(i>=1&&i<=3) T[i-1]=e;
}
void Max(Triplet T,ElemType &e) {//初始条件:三元组T已存在;操作结果:用e返回T的三个元素中的最大 值
浙江大学城市学院实验报告
课程名称
数据结构基础
实验项目名称 实验二 抽象数据类型的表示和实现
学生姓名 专业班级 学号
实验成绩 指导老师(签名 )
日期 2014-10-9
1. 实验目的和要求 1、通过抽象数据类型三元组的表示和实现,了解抽象数据类型的定义
方式。 2、掌握抽象数据类型的定义方式和用C语言实现的方法。 3、熟悉如何运用主函数检验各基本操作函数的正确性的具体操作。
int i,max; max=T[0]; for(i=0;i<=2;i++)
if(T[i]>max) max=T[i];
e=max; }
void Min(Triplet T,ElemType &e) {//初始条件:三元组T已存在;操作结果:用e返回T的三个元素中的最小 值
int i,min; min=T[0]; for(i=0;i<=2;i++)
{ // 操作结果:构造三元组T,依次置T的3个元素的初值为v1,v2和
v3
if (!(T=(ElemType *) malloc (3*sizeof(ElemType)))) //申请空间
exit(0);
// 申请空间失败,退出
T[0]=v1; T[1]=v2; T[2]=v3;
return 1;
T[0]=v1; T[1]=v2; T[2]=v3; return 1; }
void DestroyTriplet(Triplet &T) {// 操作结果:三元组T被销毁
free(T); T=NULL; return; }
void Get(Triplet T,int i,ElemType &e) {//初始条件:三元组T已存在,1≤i≤3;操作结果:用e返回T的第i元的 值
一个含抽象数据类型的软件模块通常应包含定义、表示和实现3个部 分。抽象数据类型通常采用以下格式定义:
ADT抽象数据类型名 { 数据对象:<数据对象的定义> 数据关系:<数据关系的定义> 基本操作:<基本操作的定义>
} ADT抽象数据类型名 (2)三元组的抽象数据类型定义及表示
我们以抽象数据类型三元组为例,说明抽象数据类型是如何定义 的。三元组实际上就是一个数据对象中有3个数据元素。三元组中元素 的数据类型,可以是整型数,也可以是字符、浮点数或者更复杂的数据 类型。
Max(T, e); printf("三元组T的最大值为:%d\n", e) ;
Min(T, e); printf("三元组T的最小值为:%d\n", e);
IsAscending(T,i); printf("i=%d (i=1:按升序排列;i=0:不按升序排列)\n", i);
IsDecending(T,i); printf("i=%d (i=1:按降序排列;i=0:不按降序排列)\n", i); printf("\n");
以下是三元组的抽象数据类型定义:
ADT Triplet{ 数据对象:D={e1, e2, e3 | e1, e2, e3∈ElemSet (ElemSet为某个数
据对象的集合)} 数据关系:R1={<e1, e2>, <e2, e3>} 基本操作: InitTriplet(&T, v1, v2, v3) 操作结果:构造三元组T,元素e1, e2和e3分别被赋以v1, v2, v3值 DestroyTriplet(&T) 操作结果:三元组T被销毁 Get(T, i, &e) 初始条件:三元组T已存在,1≤i≤3 操作结果:用e返回T的第i元的值 IsAscending(T) 初始条件:三元组T已存在 操作结果:如果T的三个元素按升序排列,则返回1,否则返回0 IsDecending(Triplet T); 初始条件: 三元组T已存在 操作结果: 如果T的三个元素按降序排列,则返回1,否则返回0 Put(&T, i, e) 初始条件:三元组T已存在,1≤i≤3 操作结果:改变T的第i元的值为e Max(T, &e) 初始条件:三元组T已存在 操作结果:用e返回T的三个元素中的最大值 Min(T, &e) 初始条件:三元组T已存在 操作结果:用e返回T的三个元素中的最小值
IsAscending(T,i); printf("i=%d (i=1:按升序排列;i=0:不按升序排列)\n", i);
IsDecending(T,i); printf("i=%d (i=1:按降序排列;i=0:不按降序排列)\n", i);
DestroyTriplet(T); printf("销毁三元组T后,T=%d\n", T); }
test1_2.h: int InitTriplet(Triplet &T, ElemType v1, ElemType v2, ElemType v3) {// 操作结果:构造三元组T,依次置T的3个元素的初值为v1,v2和v3
if (!(T=(ElemType *) malloc (3*sizeof(ElemType)))) exit(0);
// 返回1,则成功
}
void Put(Triplet &T,int i,ElemType e) {//初始条件:三元组T已存在,1≤i≤3;操作结果:改变T的第i元的值为e
if(i>=1&&i<=3) T[i-1]=e;
//改变T的第i元的值,e为改变的数据,将其值赋给T的第i元的值 }
四. 实验结果与分析
Triplet T; ElemType e; int i;
InitTriplet(T, 1, 2, 3); printf("构造三元组T,依次置T的3个元素的初值为:T[0]=%d,