参考严蔚敏/吴伟民版《数据结构-C语言版》
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。
- 线性表的动态分配顺序存储结构
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
#define LISTINCREMENT 10 // 线性表存储空间的分配增量
// 当因为插入新元素而存储空间不足时,增加一个大小为LISTINCREMENT个数据元素的空间
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量
}SqList;
Status InitList_Sq(SqList &L){
// 构造一个空的线性表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 ListInst_Sq(SqList &L, int i, ElemType e){
// 在顺序线性表L中第i个位置之前插入新元素e
// 1<=i<=ListLength_Sq(L)+1
if(i<1||i>L.length+1) return ERROR; // i不合法
if(L.length >= L.listsize){ //当前存储空间不足,增加分配
newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
if(!newbase) exit(OVERFLOW); // 内存分配失败
L.elem = newbase;
L.listsize += LISTINCREMENT;
}
q = &(L.elem[i-1]); // q为插入的位置
for(p=&(L.elem[L.length-1]; p>=q; --p){
*(p+1) = *p;
}
*q = e;
++L.length;
return OK;
}
Status ListDelete_Sq(SqList &L, int i, ElemType &e){
// 在顺序线性表L中删除第i个元素,用e返回其值
// 1<=i<=ListLength_Sq(L)
if((i<1) || (i>L.length)) return ERROR;
p = &(L.elemp[i-1]);
e = *p; // 第i个元素的值
q = L.elem + L.length -1; // 这里q指向表中最后一个元素
for(++p; p<=1; ++p){ // 这里表示第i个元素后面所有指针前移一位,即忽略——删除掉第i个元素
*(p-1) = *p;
}
--L.length;
return OK;
}
int LocateElem_Sq(SqList L, ElemType e, Status (* compare)(ElemType, ElemType)){
// 在顺序线性表L中查找第一个与e满足compare关系的元素的位置
int i = 1;
p = L.elem; // p是一个指针,指向的也是指针,既是一个指针的指针
while(i<=L.length && !(* compare)(*p++, e)){
++i;
}
if(i < L.length) return i;
else return 0;
}
void MergeList_Sq(SqList La, SqList Lb, SqList &Lc){
// 已知顺序线性表La和Lb的元素已经按值非递减排列, 归并La和Lb得到新的顺序线性表Lc
pa = La.elem; pb = Lb.elem;
Lc.listsize = Lc.length = La.length + Lb.length;
// 注意这里的pc是一个指针变量,初始化为指向Lc的elem成员的首地址
pc = Lc.elem = (ElemTpye )malloc(Lc.listsize * sizeof(ElemType));
if(!Lc.elem) exit(OVERFLOW);
pa_last = La.elem + La.length -1;
pb_last = Lb.elem + Lb.length -1;
while(pa<=pa_last && pb <=pb_last){
if(*pa < *pb) *pc ++= *pa++;
else *pc++ =*pb++;
}
// 下面看还有谁有剩余的元素,将其追加到Lc后
while(pa <= pa_last) *pc++ = *pa++;
while(pb <= pb_last) *pc++ = *pb++;
}
- 注意数组名确实指向数组的第一个元素的地址,但是不能移动;可以声明一个同类型的指针变量来移动读取数组中的元素