拨开顺序表的层层迷雾
晓看天色暮看云,行也思君,坐也思君!我们一起来了解一下顺序表吧!
目录
顺序表是什么?
创建顺序表:
初始化顺序表:
顺序表增加容量和数据:
顺序表删除:
顺序表的查询:
顺序表的插入和删除指定位置:
顺序表打印:
顺序表销毁:
结语:
顺序表是什么?
顺序表使用一段存储单元依次存储数据元素的线性结构,分为静态顺序表和动态顺序表,静态顺序表的长度是固定的,而动态顺序表会随着你想要多大的空间进行开辟,不会造成空间不够用,抑或是空间浪费;
创建顺序表:
想必大家都知道结构体,它可以创建一个数组进行数据的增删查改,但是如果是数组的话,长度固定不方便,所以我们要定义一个顺序表指针,因为要扩容和个数,所以我们还要定义两个变量;因为我们是以整型数据,所以接下来用int。
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* arr;
int size;//顺序表数据个数
int capacity;//顺序表容量
}SL;
初始化顺序表:
一般我们将不是指针的置为0,将指针类型的置为空(NULL),因为我们传形参的是指针,所以访问结构体定义的变量时用" -> ",接下来我们创建一个函数进行初始化。
void SLInit(SL* ps)
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
顺序表增加容量和数据:
为了能够方便代码的减少,所以我们单独创建一个函数来检查容量,如果容量不够,我们需要进行扩容,扩容也不是随便扩,防止扩容太多,差不多2倍就好了。
void SLCheckCapacity(SL* ps)
{
if (ps->size == ps->capacity)//个数已满
{
SLDataType* newcapacity = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);
if (newcapacity == NULL)//扩容失败
{
perror("realloc fail");
return;
}
ps->capacity *= 2;
}
}
头插:
当我们要插入表头数据,我们需将后面的数据依次往后移,插入数据,如图所示:
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
int i = 0;
for (i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[0] = x;//头个数据置为x;
ps->size++;//增加一个总个数
}
尾插:
尾插我们只需将最后一个数置为传入的数据,再将总个数加一。
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);//检查容量
ps->arr[ps->size++] = x;
}
顺序表删除:
头删:
我们通过循环用后面的值将前面的值覆盖即可,并将总个数减一。
void SLPopFront(SL* ps)
{
assert(ps);
assert(ps->size > 0);//防止顺序表没有数据
int i = 0;
for (i = ps->size - 1; i > 0; i--)
{
ps->arr[i - 1] = ps->arr[i];
}
ps->size--;//减少一个总个数
}
尾删:
尾删非常简单,只需要将总个数减一,就能尾删成功了哦!
void SLPopBack(SL* ps)
{
assert(ps->size > 0);//防止顺序表为空
ps->size--;
}
顺序表的查询:
我们只需使用循环,进行数据的遍历,就能够找到我们想要的数据了。
int SLFindData(SL* ps, SLDataType x)
{
assert(ps);
int i = 0;
for (int i = 0; i < ps->size; i++)
{
if (ps->arr[i] == x)//判断是否是我们要找的数据
return x;
else
return -1;
}
}
顺序表的插入和删除指定位置:
我们可知先往后移,再插入,如果先插入,再后移会导致数据被覆盖,从而数据缺失!
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);//检查是否超过
SLCheckCapacity(ps);//看容量是否足够
for (int i = ps->size; i > pos; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;//插入指定位置
ps->size++;
}
首先我们得定义一个变量,让它去表示我们想要的指定位置,然后找其下一个位置,再用循环从后往前进行移动,并覆盖掉了指定位置。
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);//检查指定位置是否超出
for (int i = pos + 1; i < ps->size; i++)
{
ps->arr[i - 1] = ps->arr[i];
}
ps->size--;//总个数减一
}
顺序表打印:
这个我们直接进行循环遍历打印就行了
void SLPrint(SL* ps)
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
}
顺序表销毁:
为了防止内存泄漏,我们需要释放掉我们使用的空间,然后置空。
void SLDestroy(SL* ps)
{
assert(ps);
free(ps->arr);//释放空间
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
结语:
聊赠一枝春,谢谢观看,bye~