本次实现的数据结构是线性表之顺序表。
顺序表中,逻辑上相邻的元素在物理位置上也相邻。
(蓝底部分可合并为完整程序)
头文件部分
//#include"c1.h"//#includestring.h#includectype.h#includemalloc.h#includelimits.h#includestdio.h#includestdlib.h#includeio.h#includemath.h#includesys/timeb.h#includestdarg.h#defineTRUE1#defineFALSE0#defineOK1#defineERROR0typedefintStatus;typedefintBoolean;
typedef的四种用法
1)为基本数据类型定义新的类型名
typedefintStatus;2)为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称
typedefstructStudent{intsid;charname[];charsex;}*PSTU,STU;
等价于STU代表了structStudent,PSTU代表了structStudent*
3)为数组定义简洁的类型名称typedefintINT_ARRAY_[];INT_ARRAY_arr;)为指针定义简洁的名称
typedefchar*PCHAR;PCHARpa;
typedef
typedefintElemType;
把int重命名为ElemType
使程序更为灵活,方便修改
顺序表的动态分配存储结构
//#include"c2-1.h"//#defineLIST_INIT_SIZE10//初始长度#defineLIST_INCREMENT2//增量structSqlist{ElemType*elem;//存储数据的内存首地址,有了首地址,就有了首元素,也就可以查找其余所有元素intlength;//当前长度intlistsize;//最大长度};
顺序表的静态分配内存
#defineLIST_INIT_SIZE10structSqlist{ElemTypeelem[LIST_INIT_SIZE];intlength;};
由此可见,实现一个顺序表需要3个元素:
首元地址、当前长度、最大容量。
十二个基本操作
顺序表初始化:
//#include"bo2-1.h"//voidInitList(SqlistL)//操作结果:构造一个空的顺序表L//L为引用类型,在函数中修改的L可以带回到主函数中{L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));//第一行是动态分配内存,运用malloc函数,连续分配了LIST_INIT_SIZE*sizeof(ElemType)个空间//为什么要强制转换为(ElemType*)类型?//因为虽然指针指向的都是同一个位置,但是如果指针所指向得数据类型定义错了,那么在访问数据元素时就会出现问题。//相当于构造了一个空的顺序表,L.elem是ElemType*类型的,元素的值也就是*(L.elem+i)if(!L.elem)//存储分配失败,L.elem没有得到地址,!L.elem成立exit(OVERFLOW);//OVERFLOW一般用于exit的参数中,比如创建指针时,一般判断一下内存是否分配成功,不成功则返回exit(OVERFLOW);L.length=0;//初始长度为0L.listsize=LIST_INIT_SIZE;//最大容量为LIST_INIT_SIZE}
销毁顺序表:
voidDestroyList(SqlistL)//初始条件:顺序表L已存在//操作结果:销毁顺序表L{free(L.elem);//释放L.elem所指向的存储空间L.elem=NULL;//L.elem不再指向任何元素L.length=0;L.listsize=0;}
置空:
voidClearList(SqlistL){L.length=0;}
判空:
StatusListEmpty(SqlistL){if(L.length==0)returnTRUE;elsereturnFALSE;}
求表长:
intListLength(SqlistL){returnL.length;}
按位查找操作:
StatusGetElem(SqlistL,inti,ElemTypee){if(i1
iL.length)returnERROR;e=*(L.elem+i-1);returnOK;}
按值查找操作:
intLocateElem(SqlistL,ElemTypee,Status(*