一、宏定义解释
ElemType :线性表数据元素数据类型
LIST_INIT_SIZE : 线性表初始数据元素容量
Status :函数返回值(一般替换int型)
error :1
INFEASIBLE :1
OK :0
二、线性表结构体
typedef struct
{
ElemType *elem; //存储空间基址
int length; //当前数据元素个数
int listsize; //当前分配的最大数据元素容量
}SqList;
三、13个基本操作
分别是:
建立线性表,清空线性表,销毁线性表
判空线性表,判满线性表,获得当前数据元素个数
获得指定位置的数据元素,定位符合一定条件的数据元素
获得一个数据元素的前驱,获得一个元素的后继
插入数据元素,删除数据元素
遍历线性表
1、建立线性表
初始条件:一个未初始化的线性表结构体
Status InitList(SqList &L)
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
//申请存储空间
if(!L.elem)
exit(0);
L.length=0;//空表的长度为0
L.list=LIST_INT_SIZE;//初始数据元素存储容量
return OK;
}
2、清空线性表
初始条件:线性表存在
操作结果:清空线性表(将当前元素个数赋值0,遍历不出任何一个元素,相当于清空线性表)
Status ClearList(SqList &L)
{
L.length=0;
return Ok;
}
3、销毁线性表
初始条件:线性表已存在
操作结果:销毁线性表
Status Destroy(SqList &L)
{
free(L.elem);
L.elem=NULL;
L.length=0;
L.listsize=0;
return OK;
}
4、判空线性表
初始条件:线性表存在
操作结果:线性表为空返回true,不为空返回false
bool ListEmpty(SqList L)//不需要对线性表的成员变量进行改变,所以不使用引用
{
return (L.length==0)?true:false;
}
5、判满线性表
初始条件:线性表存在
操作结果:若线性表已满返回true,否则返回false
bool ListFull(SqList L)
{
return (L.length==L.listsize)?true:false;
}
6、获取线性表当前元素个数
初始条件:线性表已存在
操作结果:返回线性表当前元素个数
int ListLength(SqList L)
{
return L.length;
}
7、获得指定位置的数据元素
初始条件:线性表存在
操作结果:获得指定位置的数据元素并赋值给e
Status GetElem(SqList L,int i, ElemType &e)
{
if(i<1||i>L.length)
exit(error);
e=*(L.elem+i-1);//(基址+i-1)即为第i个元素的地址
return OK;
}
8、定位元素(获得符合一定条件的数据元素的位序)
初始条件:线性表已存在
操作结果:返回L中第一个与e满足关系的元素的位序,若不存在返回0
(注意:compare()表示一个关系判定函数,满足返回值为1,否则返回值为2,使用函数指针,方便调用)
int LocateElem(SqList L,ElemType e,status(*compare)(ElemType,ElemType))
{
Elem *p=L.elem; //P的初值为第一个元素的存储位置
int i=1;//i的初值为第一个元素的位序
while(i<=L.length&&!compare(*p++,e))//越界或已找到满足条件的元素
//i的最大可能值为L.length+1
{
if(i<=L.length)
return i;
else
return 0;
}
9、返回前驱
初始条件:线性表已存在,数据元素存在前驱
操作结果:查找数据元素,若线性表中有该元素且前驱存在,将前驱拷贝给一个与数据元素数据类型相同的变量;若前驱不存在,上述变量无定义
//返回前驱,equal要提前声明
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
int a;
a=LocateElem(L,cur_e,equal);
if(!a||a==1)
{
cout<<"查找失败"<<endl;
return error;
}
pre_e=*(L.elem+a-2);
return OK;
}
10、返回后继
初始条件:线性表已存在,数据元素存在后继
操作结果:查找数据元素,若线性表中有该元素且后继存在,将后继拷贝给一个与数据元素数据类型相同的变量;若后继不存在,上述变量无定义
Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
int a;
a=LocateElem(L,cur_e,equal);
if(!a||a==L.length)
{
cout<<"查找失败"<<endl;
return error;
}
next_e=*(L.elem+a);
return OK;
}
11、插入一个数据元素
初始条件:线性表存在
操作结果:在L中第i个元素之前插入新的元素e,L的长度加1
Status ListInsert(SqList &L,int i,ElemType e)
{
ElemType *newbase,*q,*p;
if(i<1||i>L.length+1)//i值不合法
return error;
if(L.length>=L.listsize) //当前存储空间已满,增加分配
{
if(!(newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))))
exit(0);//分配存储空间失败
L.elem=newbase;//新基址
L.listsize+=LISTINREMENT;//增加存储容量
}
q=L.elem+i-1;//q为插入位置
for(p=L.elem+L.length-1;p>=q;--p)
{ *(p+1)=*p;//给插入位置之后的元素赋值达到之后元素后移一位的效果
}
*q=e;//插入e
++L.length;
return OK;
}
12、删除元素
初始条件:线性表已存在
操作结构:删除第i个数据元素并返回其值,L的长度减1
Status ListDelete(SqList &L,int i,ElemType &e)
{
ElemType *p,*q;
if(i<1||i>L.length)//i值不合法
return error;
p=L.elem+i-1;//p为被删除元素的位置
e=*p;//被删除元素的值赋给e
q=L.elem+L.length-1;//表尾元素的位置
for(++p;p<=q;++p)
*(p-1)=*p;
L.length--;
return OK;
}
13、遍历线性表
初始条件:线性表已存在
操作结果:依次对L的每个元素使用函数f(),f()可以是输出函数,一旦操作失败,则操作失败
Status ListTraverse(SqList L, void(*f)(ElemType&))
{
ElemType *p=L.elem;
int i;
for(i=1;i<=L.length;i++)
f(*p++);
cout<<endl;
return OK;
}