记得大二的时候学习严蔚敏大神的《数据结构》,满本书的抽象结构,抽象这个,抽象那个,直接整蒙了。最困难的就是概念本来就晦涩难懂,而且书里面也没有可以直接运行的代码,真头疼。好在最近发现高一凡编写的《数据结构算法解析》,里面是全是按照严奶奶的《数据结构》一书编排的代码。终于可以把数据结构全部转化成代码的形式了,趁着现在有时间再把数据结构以代码的形式梳理一遍,再提高一点点能力。 今天复习了数据结构第一章绪论,借鉴高一凡的《数据结构算法解析》,用代码实现了抽象数据类型的表示和实现,还有复习了引用&的用法。至于第一章中讲到的时间复杂度和空间复杂度,大概看来一下。
注意:
1. 抽象数据类型(Abstract Data Type ,ADT)是指一个数学模型以及定义在该模型上的一组操作(教材P7)。当然这个抽象数据类型也就是严奶奶写的数据结构的精髓----抛开具体的数据类型来讲解数据结构。
2.其中教材P9中的例1-6就是一个抽象数据类型三元组定义的例子,这个定义可以看出抽象数据类型是如何定义的。当然这些都不是重点,这些我们《数据结构》开课的时候都学过,重点是如何用具体的代码来表示和实现抽象数据类型。
3.还要讲解几个代码中的概念:1 )数据结构的表示(存储结构)用类型定义(typedef)描述,例 typedef int Status //该语句的意思是在程序int的另一别名是Status,用Status表示int;2)在代码中方法的形参表中,以&打头的参数是C++的引用,引用类型的变量,其值若在函数张发生变化,则变化的值会带回主调函数中;3)程序中数据元素类型约定为ElemType。
代码实现抽象数据类型的八个函数(教材P9)
#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<math.h>//其中定义OVERFLOW为3 #define OK 1 #define ERROR 0 typedef int Status;//Status表示函数的类型,其值是函数的结果状态码 typedef int ElemType;//定义抽象数据类型ElemType在本程序中为整型s In typedef ElemType *Triplet;//由InitTriplet分配3个元素存储空间,Triplet类型是ElemType类型的指针,存放ElemType类型的地址 Status InitTriplet(Triplet &T,ElemType v1,ElemType v2,ElemType v3){ //操作结果:构造三元组T,依次置T的3个元素的初值为v1,v2和v3(教科书第12页) T=(ElemType *)malloc(3* sizeof(ElemType)); if(!T) exit(OVERFLOW);//分配失败则退出 T[0]=v1,T[1]=v2,T[2]=v3; return OK; } Status Get(Triplet T,int i,ElemType &e){ //初始条件:三元组T已存在,1≤i≤3。操作结果:用e返回T的第i元的值(教科书第12页) if(i<1||i>3)//i不在三元组的范围之内 return ERROR; e=T[i-1];//将三元组T的第i个元素的值赋给e return OK; } Status Put(Triplet &T,int i,ElemType e){//此处的引用符&可加可不加,教科书上加了 //初始条件:三元组T已存在,1≤i≤3。操作结果:改变T的第i元的值为e(教科书第12页) if(i<1||i>3) return ERROR; T[i-1]=e; return OK; } Status IsAscending(Triplet T){//教科书第13页 //初始条件:三元组T已存在。操作结果;如果T的3个元素按升序排列,则返回1,否则返回0 return (T[0]<=T[1]&&T[1]<=T[2]); } Status IsDescending(Triplet T){ //初始条件;三元组T已存在。操作结果;如果T的3个元素按降序排列,则返回1,否则返回0 return (T[0]>=T[1]&&T[1]>=T[2]); } Status Max(Triplet T,ElemType &e){ //初始条件:三元组T已存在。操作结果:用e返回指向T的最大元素的值(教科书第13页) e=(T[0]>=T[1])?(T[0]>=T[2]?T[0]:T[2]):(T[1]>=T[2]?T[1]:T[2]); return OK; } Status Min(Triplet T,ElemType &e){ //初始条件:三元组T已存在。操作结果:用e返回指向T的最小元素的值(教科书第13页) e=(T[0]<=T[1])?(T[0]<=T[2]?T[0]:T[2]):(T[1]<=T[2])?T[1]:T[2]; return OK; } Status DestroyTriplet(Triplet &T){ //操作结果:三元组T被销毁(教科书第12页) free(T);//释放T所指的三元组存储空间 T=NULL;//T不在指向任何存储单元 return OK; } void PrintT(Triplet T)//依次输出三元组的值 { printf("%d,%d,%d\n",T[0],T[1],T[2]); } void PrintE(ElemType e)//输出元素的值 { printf("%d\n",e); } void main(){ Triplet T; ElemType m; Status i; i=InitTriplet(T,5,7,9);//初始化三元组T,其3个元素依次为5,7,9 printf("调用初始化函数后,i=%d(1:成功)。T的3个值为",i); PrintT(T);//输出T的3个值 i=Get(T,2,m);//将三元组T的第2个值赋给m if(i=OK){//调用Get()成功 printf("T的第2个值为"); PrintE(m);//输出m(=T[1]) } i=Put(T,2,6);//将三元组T的第2个值改为6 if(i==OK){//调用Put()成功 printf("将T的第2个值改为6后,T的3个值为"); PrintT(T);//输出T的3个值 } i=IsAscending(T);//测试升序函数 printf("调用测试升序的函数后,i=%d(0:否 1:是)\n",i); i=IsDescending(T);//测试降序的函数 printf("调用测试降序的函数后,i=%d(0:否 1:是)\n",i); if(i=Max(T,m)==OK){ printf("T中的最大值为"); PrintE(m);//输出最大值m } if(i=Min(T,m)==OK){ printf("T中的最小值为"); PrintE(m);//输出最小值m } DestroyTriplet(T);//函数也可以不带返回值 printf("销毁T后,T=%u\n",T); }
#include<stdio.h> void fa(int n){//在函数中改变n,将不会带回主调函数(主调函数中的n仍是原值) n++; printf("在函数fa中:n=%d\n",n); } void fb(int &n){//由于n为引用类型,在函数中改变n,其值将带回主调函数 n++; printf("在函数fb中:n=%d\n",n); } void main(){ int n=1; printf("在主程序中,调用函数fa之前:n%d\n",n); fa(n); printf("在主程序中,调用函数fa之后:n=%d\n",n); printf("在主程序中,调用函数fb之前:n=%d\n",n); fb(n); printf("在主程序中,调用函数fb之后:n=%d\n",n); }