检查为顺序表所准备的存储空间是否够用的函数:如果存放在顺序表中的元素个数已经等于了顺序表的容量,那就需要为顺序表新增存储空间,如果原空间原本就为空,则为其新申请的空间为4字节,否则新申请的空间大小为原空间的二倍。
void SeqListCheckCapacity(SL* ps)
{
if (ps->capacity == ps->size)
{
SLDataType newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newcapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
}
向顺序表中尾插一个元素:先用之前定义的判断存储空间是否已满的函数,这些申请等过程因为之前我已经定义了,这里就不需要再考虑了,拿过来直接用即可。然后将准备新插入的元素放到数组的最后一个位置上,即a[size]=x,由于这些变量都定义在结构体中,因此需要用结构体的指针来调用这些变量:ps->a[ps->size]=x。最后记得新插入了一个元素,要改变其中的元素个数size。
void SeqListPushBack(SL* ps, SLDataType x)
{
SeqListCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
在顺序表中尾删一个元素:首先要用断言函数,确定该顺序表中不止一个元素,即ps->size>0(这里也有其它的办法,但是用断言函数assert是最方便的方法,而且在出错时,非常便于找到出错的位置),最后,和尾插类似,少了一个元素,不要忘了给size减去1。
void SeqListPopBack(SL* ps)
{
assert(ps->size > 0);
ps->size--;
}
在顺序表中头插一个元素:想要在顺序表中头插一个元素,由于顺序表中原先每一个位置都有元素占着,因此想要插入一个元素,需要将整个线性表中的所有元素向后挪一位,给插入的元素空出位置。如果从前向后依次挪,元素之间会相互覆盖,因此只能从后向前挪。
void SeqListPushFront(SL* ps, SLDataType x)
{
SeqListCheckCapacity(ps);
int end = ps->size - 1;//这里end就代表数组中最后一个元素的下标
while (end >= 0)
{
ps->a[end+1] = ps->a[end];
end--;
}
ps->a[0] = x;
ps->size++;
}
删去线性表中的第一个元素:不需要额外的处理,只需要从第二个元素到最后一个依次向前挪一位,覆盖掉前面的元素即可。
void SeqListPopFront(SL* ps)
{
assert(ps->size > 0);//只要是删除相关的,都需要断言函数,因为一个空的线性表没有删除的意义
int i = 0;
int front = ps->size - 1;
while (i<front)
{
ps->a[i] = ps->a[i + 1];
i++;
}
ps->size--;
}
在顺序表中寻找一个数:简单的遍历思想,从第一个数开始一次比较,相等则直接返回下标,遍历完整个数组之后都没有则跳出循环返回-1。
int SeqListFind(SL* ps, SLDataType x)
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (ps->a[i] == x)
return i;
}
return -1;
}
在顺序表中的特定位置上插入一个元素:由于顺序表是连续存储的,因此需要对插入的位置进行一个断言。如果要在下标为pos处插入元素,则需要把当前在下标pos及其后的所有元素从后向前依次向后挪动一位,再把要插入的元素插入到最终空出来的位置上。
void SeqListInsert(SL* ps, int pos, SLDataType x)
{
assert(pos >= 0 && pos <= ps->size);//插入的位置只能是在数组的第一个元素的位置或者当前数组末尾的下一个位置
SeqListCheckCapacity(ps);
int end = ps->size - 1;//同上,end代表数组当前最后一个元素的下标
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
在顺序表指定位置删除一个元素:仍要先断言,待删除节点的下标处在顺序表目前的下标范围内。然后将待删除下标对应节点后面的每一个元素都向前挪动一位即可。
void SeqListErase(SL* ps, int pos)
{
assert(pos >= 0 && pos < ps->size);
int begin = pos + 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}