在之前的顺序表中,我们使用数组来存储数据元素,但是这样的结构有很大的隐患。在一些情况下,我们无法事先确定数据元素的规模。如果数据元素很少的话,数组很多空间是浪费的, 如果数据元素比较大的话,数组可能会出现溢出的危险,这比单纯的浪费空间要严重的多。C语言是不支持动态数组的,但是我们可以通过指针实现这一个特性
顺序表的结构
- 这里和前面使用数组实现的顺序表类似,使用的是指针基址来模拟动态数组,使用 size 来表示当前可以使用的元素数,如果不够的话,我们待会再分配。
typedef char Elemtype;
typedef struct{
Elemtype *elem;
int length;
int size;
}SqList;
顺序表的基本运算
初始化顺序表
/*
初始化顺序表
*/
Status InitList(SqList *L)
{
L->length = 0;
L->size = INIT_SIZE;
L->elem = (Elemtype *)malloc(sizeof(Elemtype)* L->size);
if (!L->elem)
return ERROR;
return OK;
}
销毁顺序表
/*
销毁顺序表
*/
Status ListDestory(SqList *L)
{
L->length = 0;
L->size = 0;
free(L->elem);
L->elem = NULL;
return OK;
}
清空顺序表
/*
清空顺序表
*/
Status ListClear(SqList *L)
{
L->length = 0;
return OK;
}
在顺序表中插入元素
/*
在顺序表中插入元素
*/
Status ListInsert(SqList *L, int i, char e)
{
int j;
Elemtype *oldElem;
if (L->length >= L->size){ //如果存储空间容量不足, 进行动态扩容
L->size += INCRE_SIZE;
oldElem = L->elem;
L->elem = (Elemtype *)realloc(L->elem, L->size * sizeof(Elemtype));
if (!L->elem){
free(oldElem);
return ERROR;
}
}
if (i < 1 || i > L->length + 1){
return ERROR;
}
for (j = L->length; j >= i; --j)
L->elem[j] = L->elem[j - 1];
L->elem[i - 1] = e;
L->length++;
return OK;
}
在顺序表中删除元素
/*
在顺序表中删除元素
*/
Status ListDelete(SqList *L, int i, char *e)
{
int j;
if (i < 1 || i > L->length)
return ERROR;
*e = L->elem[i - 1];//保存删除的元素
for (j = i - 1; j < L->length - 1; ++j)
L->elem[j] = L->elem[j + 1];
L->length--; //删除或者增加一个元素之后,长度立即变化(如何不做这一步的话,顺序表是不会工作的)
return OK;
}