//顺序表结构体定义#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedefint ElemType;typedefstruct{
ElemType* elem;//基地址int length;//当前长度,即有效元素个数int listsize;//当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;//顺序表12种基本操作函数声明
Status InitList(SqList* L);
Status DestoryList(SqList* L);
Status ClearList(SqList* L);
Status ListEmpty(SqList L);intListLength(SqList L);
Status GetElem(SqList L,int i, ElemType* e);intLocateElem(SqList L, ElemType e,Status(*compare)(ElemType, ElemType));
Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e);
Status NextElem(SqList L, ElemType cur_e, ElemType* next_e);
Status ListInsert(SqList* L,int i, ElemType e);
Status ListDelete(SqList* L,int i, ElemType *e);
Status ListTraverse(SqList L, Status (*visit)(ElemType*));//两个辅助函数
Status compare(ElemType x, ElemType y);
Status visit(ElemType *);
函数定义
//顺序表的12个基本操作函数定义
Status InitList(SqList* L){
L->elem =(ElemType*)malloc(LIST_INIT_SIZE *sizeof(ElemType));//创建空表if(!L->elem)exit(-1);//判断是否创建成功
L->length =0;//初始长度为0
L->listsize = LIST_INIT_SIZE;//初始分配LIST_INIT_SIZE个sizeof(int)大小的容量return OK;}
Status DestoryList(SqList* L){free(L->elem);//释放主调函数中L中的elem指针指向的数组占用的空间
L->elem =NULL;//将elem指针变量本身置空
L->length =0;
L->listsize =0;return OK;}
Status ClearList(SqList* L){
L->length =0;return OK;}
Status ListEmpty(SqList L){if(L.length ==0)return TRUE;elsereturn FALSE;}intListLength(SqList L){return L.length;}
Status GetElem(SqList L,int i, ElemType* e){if(i<1|| i>L.length)exit(ERROR);//若i不符合范围*e =*(L.elem + i -1);return OK;}intLocateElem(SqList L, ElemType e,Status(*compare)(ElemType, ElemType)){int i =1;//当前位置
ElemType* p = L.elem;//p扫描while(i <= L.length &&!(*compare)(e,*p)){
p++;
i++;}//循环结束, 有两种情况if(i <= L.length)return i;elsereturn0;}
Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e){int i =2;//从第二个开始,因为第一个元素没有前驱元素
ElemType* p = L.elem +1;//扫描指针也从第二个开始while(i <= L.length &&!(*p == cur_e)){
i++;
p++;}if(i > L.length)return INFEASIBLE;else{*pre_e =*(--p);return OK;}}//PriorElem方法二
Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e){
ElemType* p = L.elem;
ElemType* q;//q指向p的后继while(p +1){
q = p +1;if(*q == cur_e){*pre_e =*p;return OK;}
p++;}return ERROR;}
Status NextElem(SqList L, ElemType cur_e, ElemType* next_e){int i =1;
ElemType* p = L.elem;while(i <= L.length -1&&!(*p == cur_e))//当扫描到最后一个元素或者满足*p == cur_e时循环结束{
i++;
p++;}if(i > L.length -1)return INFEASIBLE;else{*next_e =*(++p);return OK;}}//NextElem方法二
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e){
ELemType *p = L.elem;while(p+1){if(*p == cur_e){*next_e =*p;return OK;}
p++;}return ERROR;}
Status ListInsert(SqList* L,int i, ElemType e){if(i<1|| i>ListLength(*L)+1)return ERROR;//当i不符合范围时if(L->length >= L->listsize)//当已分配的储存空间用完时{
ElemType* newbase;//新基地址
newbase =(ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType));if(NULL== newbase)//判断是否创建成功{printf("空间分配失败!\n");exit(-1);}
L->elem = newbase;//使用新基地址
L->listsize += LISTINCREMENT;//存储容量增大}//使原数组下标为i-1及之后的元素后移一位
ElemType* q,* p;
q = L->elem+i-1;//q指向第i(下标i-1)个元素
p = L->elem+L->length-1;//p指向最后一个元素for(; p >= q; p--)*(p +1)=*p;//后移*q = e;//插入
L->length++;//表长增加return OK;}
Status ListDelete(SqList* L,int i, ElemType *e){if(i<1|| i>L->length)return ERROR;//当i超出范围时
ElemType *q,*p;//q删除位置,即下标为i-1的指针; p线性表最后一位元素的指针
q = L->elem+i-1;
p = L->elem+L->length-1;*e =*q;//e存放删除的值for(q++; q <= p; q++)*(q -1)=*q;//前移
L->length--;//表长减1return OK;}
Status ListTraverse(SqList L, Status (*visit)(ElemType*)){
ElemType* p = L.elem;//p扫描指针,从第一个元素开始int i;for(i=1; i<=ListLength(L); i++)visit(p++);//把指针传递给visit,则可以通过visit修改值printf("\n");return OK;}
测试
//顺序表的12个基本操作检测#include"SqList.cpp"intmain(){
SqList L;if(InitList(&L))printf("创建成功!\n");elseprintf("创建失败!\n");//求表长printf("表长为:%d\n",ListLength(L));//判空if(ListEmpty(L))printf("表空!\n");elseprintf("非空!\n");//插入元素
ElemType i;for(i =1; i <=20; i++){if(ListInsert(&L,1, i))printf("头插入成功:%d\n", i);elseprintf("头插入失败!\n");}//判表空if(ListEmpty(L))printf("空!\n");elseprintf("非空!\n");//表长printf("表长为:%d\n",ListLength(L));//遍历ListTraverse(L, visit);//取元素if(GetElem(L,2,&i))printf("取第2个元素:%d\n", i);elseprintf("获取失败!\n");//定位元素int n =LocateElem(L,2, compare);if(i !=0)printf("与2相关的元素是第%d个\n", n);elseprintf("定位失败!\n");
n =LocateElem(L,9, compare);if(n !=0)printf("与9相关的元素是第%d个\n", n);elseprintf("定位失败!\n");//前后继元素if(PriorElem(L,2,&i))printf("2的前元素:%d\n", i);elseprintf("获取失败!\n");if(PriorElem(L,8,&i))printf("8的前元素:%d\n", i);elseprintf("获取失败!\n");if(NextElem(L,2,&i))printf("2的后元素:%d\n", i);elseprintf("获取失败!\n");if(NextElem(L,1,&i))printf("1的后元素:%d\n", i);elseprintf("获取失败!\n");//删除if(ListDelete(&L,1,&i))printf("删除第%d个元素:%d\n",1, i);elseprintf("删除失败!\n");if(ListDelete(&L,3,&i))printf("删除第%d个元素:%d\n",3, i);elseprintf("删除失败!\n");//表长printf("表长为:%d\n",ListLength(L));//遍历ListTraverse(L, visit);//清空if(ClearList(&L))printf("清空成功!\n");elseprintf("清空失败!\n");//判表空if(ListEmpty(L))printf("空!\n");elseprintf("非空!\n");//表长printf("表长为:%d\n",ListLength(L));//遍历ListTraverse(L, visit);//销毁链表if(DestoryList(&L))printf("销毁成功!\n");elseprintf("销毁失败!\n");return0;}
Status compare(ElemType x, ElemType y){if(x == y)return OK;elsereturn ERROR;}
Status visit(ElemType *e){printf("%d ",*e);return OK;}