💨 动态储存顺序表
💢引语
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,即静态顺序表静态顺序表,静态顺序表我已经写好了,这次我主要来介绍 动态存储顺序表。
静态和动态的对比:静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。
🌊顺序表的基本功能
💦1.初始化
//动态顺序存储--按需存储空间
typedef int SLDataType; //SLDataType的类型根据实际存储的数据类型而定
typedef struct SqList
{
SLDataType* a;
int size; //记录存储多少个有效数据
int capacity; //空间容量的大小
}SL;
//初始化
void SLInit(SL* ps)
{
assert(ps); //断言,判断是否为空
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
代码解释:
- 定义一个SLDataType类型指针a记录动态开辟的数组初始地址
- size记录多少个有效数据,capacity为动态数组暂时性的空间大小,当size与capacity相等时,空间需要扩容。
💦2.销毁
//销毁
void SLDestroy(SL* ps)
{
assert(ps); //断言
if(ps->a!=NULL)
{
free(ps->a); //释放创建的动态数组
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
}
代码解释:
开辟的动态空间不用了要记得释放,如果不释放将导致严重后果!
如果程序结束,动态开辟的空间会被操作系统回收!
如果程序不结束,动态开辟的空间是不会被自动回收的,就会形成内存泄漏问题!
释放完的指针也要置空,不置空的话,这个指针就是野指针,如果你以后万一对这个指针进行解引用,就会造成非法访问!
💦3.打印
//打印
void SLPrint(SL* ps)
{
for (int i = 0;i < ps->size;i++)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
打印功能的实现比较简单,我就不做过多的赘述了
💦4.扩容
//扩容
void SLCheckCapacity(SL* ps)
{
if (ps->size == ps->capacity) //先判断是否有空间
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//ps->a=(SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType)); 不要这样接收,扩容失败会返回空指针
SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
if (tmp == NULL)
{
//扩容失败
perror("realloc fail");
exit(-1);
}
else
{
ps->a = tmp;
ps->capacity = newCapacity;
}
}
}
当size等于capacity时,动态开辟数组空间容量已经存满,需要扩容。
💦5.尾插尾删
//尾插
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps); //先检查空间容量是否存满,存满需扩容
ps->a[ps->size] = x;
ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{
//暴力检查
assert(ps->size > 0);
ps->size--;
}
尾插尾删功能的测试
void TestSeqList1()
{
SL sl;
SLInit(&sl); //注意初始化传的是实参的地址
SLPushBack(&sl, 1); //尾插
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPushBack(&sl, 5);
SLPushBack(&sl, 6);
SLPushBack(&sl, 7);
SLPushBack(&sl, 8);
SLPushBack(&sl, 9);
SLPrint(&sl);
SLPopBack(&sl); //尾删
SLPrint(&sl);
SLPushBack(&sl, 9);
SLPrint(&sl);
SLDestroy(&sl); //用完销毁
}
int main()
{
</