//库函数头文件包含
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//顺序表的存储结构定义
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType; //假设线性表中的元素均为整型
typedef struct{
ElemType* elem; //存储空间基地址
int length; //表中元素的个数
int listsize; //表容量大小
}SqList; //顺序表类型定义
//构造一个空的线性表L
Status InitList(SqList &L){
L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); //开辟一段空间
if(!L.elem)
exit(OVERFLOW); //储存分配失败
L.length = 0; //空表长度为0
L.listsize = LIST_INIT_SIZE; //初始储存容量
return OK;
}
//向线性表末尾中插入一个元素
Status InsertList(SqList &L, ElemType e){
if(L.length >= L.listsize){ //当储存空间已经满了的时候,要重新开辟空间
L.elem = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.listsize += LISTINCREMENT;
}
*(L.elem + L.length) = e;
++L.length;
return OK;
}
//销毁线性表L。
Status DestroyList(SqList &L){
if(L.elem)
free(L.elem); //释放L.elem
L.elem = NULL; //将L.elem赋值为空
return OK;
}
//将线性表重置为空表
Status ClearList(SqList &L){
L.length = 0; //只需将元素的个数赋值为0就相当于重置为空表不需要关注里面的内容
return OK;
}
//判断线性表是否为空
Status ListEmpty(SqList L){
if(L.length = 0)
return TRUE; //如果元素个数为0就返回TRUE
return FALSE; //否则返回FALSE
}
//获得L中数据元素个数
int ListLength(SqList L){
return L.length; //直接返回元素个数就可以
}
//获得线性表中第i个元素的值
Status GetElem(SqList L, int i, ElemType &e){
if(i > L.length) //如果i超出所存值的范围,就找不到第i个值,返回ERROR
return ERROR;
e = *(L.elem + i);
return OK;
}
bool com(ElemType e1, ElemType e2){
if(e2 > e1)
return true;
else
return false;
}
//返回L中第一个与e满足关系compare()的数据元素的位序。
int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType e1, ElemType e2)){
int location;
int flag = 0;
for(location = 0; location < L.length; ++location){
if(compare(e, *(L.elem + location))){
flag = 1;
break;
}
}
if(flag == 1)
return location + 1;
else
return -2; //如果不存在返回一个负值;
}
//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败pre_e无定义
Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e){
for(int i = 0; i < L.length; ++i){
if(*(L.elem + i) == cur_e && i != 0){
pre_e = *(L.elem + i - 1);
return OK;
}
}
return ERROR;
}
//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败next_e无定义
Status NextElem(SqList L, ElemType cur_e, ElemType &next_e){
for(int i = 0; i < L.length; ++i){
if(*(L.elem + i) == cur_e && i != L.length - 1){
next_e = *(L.elem + i + 1);
return OK;
}
}
return ERROR;
}
//在L中第i个位置之前插入一个新的数据元素e,L的长度加1
Status ListInsert(SqList &L, int i, ElemType e){
if(i < 1 || i > L.length) //当输入的i不合法的时候,直接返回ERROR
return ERROR;
if(L.length >= L.listsize){ //当储存空间已经满了的时候,要重新开辟空间
L.elem = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.listsize += LISTINCREMENT;
}
ElemType *p = L.elem + L.length - 1, *q = L.elem + i - 1;
for(p; p >= q; --p)
*(p + 1) = *p;
*q = e;
++L.length;
return OK;
}
//删除L中第i个数据元素,并用e返回其值,L的长度减1
Status ListDelete(SqList &L, int i, ElemType &e){
if(i < 1 || i > L.length)
return ERROR;
ElemType *p = L.elem + i - 1, *q = L.elem + L.length - 1;
e = *p;
for(p; p < q; ++p)
*p = *(p + 1);
--L.length;
return OK;
}
Status print(ElemType e){
printf("%d ", e);
return OK;
}
//依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败
Status ListTraverse(SqList L, Status (*visit)(ElemType e)){
ElemType *p = L.elem, *q = L.elem + L.length;
for(p; p < q; ++p){
if(visit(*p) != OK)
return ERROR;
}
return OK;
}
//顺序表的就地逆置
void ListReverse_Sq(SqList &L){
int n = L.length / 2;
int tp;
for(int i = 0; i < n; i++){
tp = *(L.elem + i);
*(L.elem + i) = *(L.elem + L.length - 1 - i);
*(L.elem+L.length - 1 - i) = tp;
}
}
//主函数
int main(){
int a;
SqList L;
InitList(L);
printf("请输入5个数:\n");
for(int i = 0; i < 5; ++i){
scanf("%d", &a);
InsertList(L, a);
}
printf("下面是visit操作结果:\n");
ListTraverse(L, print);
putchar('\n');
printf("下面是ListInsert操作结果:\n");
ListInsert(L, 2, 5);
ListTraverse(L, print);
putchar('\n');
printf("下面是长度结果:\n");
printf("%d\n", ListLength(L));
printf("下面是ListDelete操作结果:\n");
ListDelete(L, 2, a);
ListTraverse(L, print);
putchar('\n');
printf("%d\n", a);
printf("下面是NextElem操作结果:\n");
NextElem(L, 2, a);
ListTraverse(L, print);
putchar('\n');
printf("%d\n", a);
printf("下面是PriorElem操作结果:\n");
PriorElem(L, 2, a);
ListTraverse(L, print);
putchar('\n');
printf("%d\n", a);
printf("下面是LocateElem操作结果:\n");
a = LocateElem(L, 2, com);
ListTraverse(L, print);
putchar('\n');
printf("%d\n", a);
printf("下面输出的是逆置后的结果:\n");
ListReverse_Sq(L);
ListTraverse(L, print);
DestroyList(L);
return 0;
}
下面是对代码的一些测试: