顺序表的建立及功能实现
顺序表的建立
静态顺序表: 会造成空间开辟的不足或者空间浪费
**动态顺序表:**使用动态开辟的数组储存
//动态顺序表
#define N 1000
typedef int SLDataType; //以后方便类型重定义
typedef struct SeqList
{
SLDataType* a; //指向动态开辟的数组
int size; //存储有效数据个数
int capacity; //空间大小
}SL;
顺序表 的数据管理
增删查改
顺序表的初始化:
void SLInit(SL* ps)
{
ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);
if (ps->a == NULL)
{
perror("malloc failed"); //打印错误
exit(-1); //让程序以异常退出
}
ps->size = 0;
ps->capacity = 4;
}
在这里我们传递的是实参的地址,这里就涉及到 形参是实参的拷贝,形参的改变不会影响实参。
主函数中的传参为:
int main()
{
SL s1;
SLInit(&s1);
return 0;
}
顺序表的销毁:
void SLDestroy(SL* ps)
{
free(ps->a);
ps->a = NULL;
ps->capacity = ps->size = 0;
}
顺序表的头插头删,尾插尾删。
首先我们来写一个函数判断顺序表的空间是否足够操作,如果不够后续操作,则需要扩容
扩容函数:
void SLCheckCapacity(SL* ps)
{
//满了要扩容
if (ps->size == ps->capacity)
{ //是之前空间的2倍
SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
if (tmp == NULL)
{
perror("realloc failed");
exit(-1);
}
ps->a = tmp;
ps->capacity *= 2;
}
}
在C语言中realloc函数会帮助我们实现扩容
那么realloc 函数的使用方法是什么呢?让我们来看一看
尾插
void SLPushBack(SL* ps, SLDataType x) //
{
SLCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
尾删
void SLPopBack(SL* ps)
{
assert(ps->a > 0);
ps->size--;
}
上述代码中的assert的作用是检查指针是否越界
头插
void SLPushFront(SL* ps, SLDataType x)
{
SLCheckCapacity(ps);
//挪动数据
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[0] = x;
ps->size++;
}
头删
void SLPopFront(SL* ps)
{
assert(ps->size > 0);
int begin = 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
++begin;
}
ps->size--;
}
在pos位置插入x
void SLPInsert(SL* ps, int pos, SLDataType x)
{
assert(pos >= 0 && pos <= ps->size);
SLCheckCapacity(ps);
int end = ps->size - 1;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[pos] = x;
ps->size++;
}
删除pos位置的值
void SLPErase(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--;
}