线性表-顺序存储结构
线性表基本概念:
线性结构的基本特征为:
集合中必存在唯一的一个“第一元素”;
集合中必存在唯一的一个 “最后元素” ;
除最后元素在外,均有 唯一的后继;
除第一元素之外,均有 唯一的前驱。
用ADT表示:
ADT List {
数据对象:
D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 }
数据关系:
R1={ <ai-1, ai > | ai-1, ai∈D, i=2,...,n }
基本操作:包括结构初始化操作、结构销毁操作、引用型操作、加工型操作
} ADT List
线性表之顺序存储结构操作
通常用数组来描述顺序存储结构,由于线性表的长度可变,所以必须动态分配一维数组。
先用结构体对其进行封装:
//线性表空间的初始存储量
#define LIST_INIT_SIZE 80
//线性表存储空间的分配增量
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct
{
ElemType* elem; //基地址
int length; //当前长度
int listsize; //当前分配的存储容量(sizeof(ElemType)为单位)
}SqList;
然后声明SqList这一数据类型的操作:
void InitList(SqList &L); //构造空的线性表
void ExtendList(SqList &L); //扩展线性表的容量->增加LISTINCREMENT
int LocateElem(SqList L,ElemType e, bool (*compare)(ElemType, ElemType)); //寻找符合条件的线性表元素
void InsertList(SqList &L, ElemType e, int i); //插入元素到线性表的某个位置,弟i个位置前
void DeleteList(SqList &L, ElemType &e, int i); //删除线性表元素,并将删除的元素赋给e
void MergeList(SqList a, SqList b, SqList &c); //将两个增序线性表增序合并
下面进行实现,注意动态内存的分配,要有错误判断:
void InitList(SqList &L)
{
L.elem = (ElemType*)malloc( LIST_INIT_SIZE * sizeof(ElemType));
if(!L.elem)
{
exit(OVERFLOW);
}
L.length = 0;
L.listsize = LIST_INIT_SIZE;
}
void ExtendList(SqList &L)
{
ElemType* newbase = (ElemType*)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof (ElemType));
if(!newbase)
{
exit(OVERFLOW);
}
L.elem = newbase;
L.listsize += LISTINCREMENT;
}
int LocateElem(SqList L, ElemType e,bool (*compare)(ElemType, ElemType))
{
int i = 1; //初始index
ElemType *p = L.elem;
while(i <= L.length && !compare(*p++, e))
{
i++;
}
if(i <= L.length)
{
return i;
}
else
{
return 0;
}
}
void InsertList(SqList &L, ElemType e, int i)
{
if(i < 1 || i > L.length + 1)
{
exit(0);
}
if(L.length + 1 > L.listsize) //增加一位后超出内存限制
{
ElemType* newbase = (ElemType*)realloc(L.elem,(L.listsize + LISTINCREMENT)*sizeof(ElemType));
if(!newbase)
{
exit(OVERFLOW);
}
L.elem = newbase;
L.listsize += LISTINCREMENT;
}
ElemType* p = &(L.elem[i-1]); //插入的位置
for(ElemType* q = &(L.elem[L.length - 1]);q >= p;q--)
{
*(q + 1) = *q;
}
*p = e;
L.length++;
}
void DeleteList(SqList &L, ElemType &e, int i)
{
if(i < 1 || i > L.length)
{
exit(0);
}
ElemType *p = &(L.elem[i - 1]);
e = *p;
ElemType *q = &(L.elem[L.length - 1]);
p++;
for(;p <= q;p++)
{
*(p - 1) = *p;
}
L.length--;
}
void MergeList(SqList a, SqList b, SqList &c)
{
ElemType *pa = a.elem;
ElemType *pb = b.elem;
c.length = a.length + b.length;
c.listsize = a.length + b.length;
c.elem = (ElemType*)malloc(c.listsize * sizeof (ElemType));
ElemType *pc = c.elem;
if(!c.elem)
{
exit(OVERFLOW);
}
ElemType *pa_last = &(a.elem[a.length - 1]);
ElemType *pb_last = &(b.elem[b.length - 1]);
while(pa <= pa_last && pb <= pb_last)
{
if(*pa >= *pb)
{
*pc++ = *pa++;
}
else
{
*pc++ = *pb++;
}
}
while(pa <= pa_last)
{
*pc++ = *pa++;
}
while(pb <= pb_last)
{
*pc++ = *pb++;
}
}