前面已经介绍了顺序表基本成员的建立,今天我们看下顺序表基本操作的实现。
typedef struct Seqlist
{
int* base;
size_t capacity;
size_t size;
}Seqlist;
首先将顺序表的框架做出来,下面的所有操作都是建立在这个基本操作之上。
我们先来看怎么将数据在线型表上存储,也就是先将数据存放到这个线型表上。我们来写出他的函数。
void InitSeqlist(Seqlist* psl,size_t sz)
{
psl->capacity = sz > 5 ? sz : 5;
psl->base = (int*)malloc(sizeof(int)*psl->capacity);
psl->size = 0;
}
但是将数据输入到线型表中绝对不会这么简单,首先你要判断这段线性表的空间是否申请成功,其次你还要考虑这个线型表是否满了,是否为空。接下来我们做出这两个函数。
首先这个两个函数不需要对其返回值进行任何操作,只需要判断其返回值是真还是假。一次用布尔型的常量
bool seqlistIsFull(Seqlist* psl);
bool seqlistIsFull(Seqlist* psl)
{
return psl->size >= psl->capacity;
}
判断是否为空
bool seqlistIsEmpty(Seqlist* psl);
bool seqlistIsEmpty(Seqlist* psl)
{
return psl->size == 0;
}
线性表存储数据一定是有序的,一般有2种方式,头插和尾插。我们前面判断线性表是为空还是为满操作就是为下面操作进行的。
首先来看尾插发创建一个线性表
bool seqlistPushBank(Seqlist* pal, int x);
bool seqlistPushBank(Seqlist* pal, int x)
{
assert(pal != NULL);
if (seqlistIsFull(pal) && _InitSeqlist(pal,x))
{
printf("顺序表已满,%d插入失败",x);
return false;
}
pal->base[pal->size++] = x;
return true;
}
`
之前博客中有提到过,不在进行代码解释
尾插
```c
bool seqlistPushFront(Seqlist*pal, int y);
bool seqlistPushFront(Seqlist* pal, int y)
{
assert(pal != NULL);
if (seqlistIsFull(pal) && _InitSeqlist(pal, y))
{
printf("顺序表已满,%d无法插入",y);
return false;
}
for (int i = pal->size; i > 0; ++i)
{
pal[i] = pal[i - 1];
}
pal->base[0] = y;
pal->size++;
return true;
}
我们怎么知道自己的顺序表功能正确呢?我们需要将这个做出一个展示函数
怎么展示,计算机展示数据肯定是一个一个展示,这时候我们就应该去想用循环打印出来。
void seqlistShow(Seqlist *psl);
void seqlistShow(Seqlist *psl)
{
for (int i = 0; i < psl->size; ++i)
{
printf("%d", psl[i]);
}
}
接下来我们来看一下头删和尾删,因为对于顺序表的基本操作无非就是增删查改。
尾删
bool seqlistPopBank(Seqlist* pal);
bool seqlistPopBank(Seqlist* pal)
{
assert(pal != NULL);
if (seqlistIsEmpty(pal))
{
printf("顺序表为空不能删除");
return false;
}
pal->size--;
return true;
}
接下来看头删
其操作也很简单,和数组操作基本上一致,就让后一个元素覆盖掉前一个元素的值就行
bool SeqlistPopFront(Seqlist* pal);
bool SeqlistPopFront(Seqlist* pal)
{
assert(pal != NULL);
if (seqlistIsEmpty(pal))
{
printf("顺序表为空不能删除");
return false;
}
for (int i = 0; i < pal->size-1; i++)
{
pal->base[i] = pal->base[i + 1];
}
pal->size--;
return true;
}
接下来我们来看按位置插入环节
bool SeqListInsertByPos(SeqList *psl, int pos, DataType x)
{
assert(psl != NULL);
if(SeqListIsFull(psl) && !_SeqListInc(psl))
{
printf("顺序表满,插入失败\n",x);
return false;
}
if(pos<0 || pos>psl->size)
{
printf("输入位置有误\n");
return false;
}
for(int i=psl->size; i>pos; --i)
{
psl->base[i] = psl->base[i-1];
}
psl->base[pos] = x;
psl->size++;
return true;
}
下面继续看按值插入,这里规定按照值插入如果有重复值,插入到先输入的值的前面
bool SeqListInsertByVal(SeqList *psl, DataType x)
{
assert(psl != NULL);
if(SeqListIsFull(psl) && !_SeqListInc(psl ))
{
printf("顺序表满,不能继续插入\n",x);
return false;
}
int i;
for(i=psl->size-1; i>=0&&x<psl->base[i]; --i)
{
psl->base[i+1] = psl->base[i];
}
psl->base[i+1] = x;
psl->size++;
return true;
}
接下来·我们来看顺序表清除和销毁工作
首先来看清除
void SeqListClear(SeqList *psl)
{
assert(psl != NULL);
psl->size = 0;
}
再看销毁
void SeqListDestroy(SeqList *psl)
{
free(psl->base);
psl->base = NULL;
psl->capacity = psl->size = 0;
}
基本上一个顺序表的增删查改就是这些
涉及到排序方面的问题后面到链表章节我们一起看。。