1.构建简单的结构体
// 动态顺序表
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* a;
int size; // 存储数据的个数
int capacity; // 存储空间的大小
}SL;
2.初始化
void SLInit(SL* psl) //初始化
{
assert(psl);
psl->a = NULL;
psl->size = psl->capacity = 0;
}
3.打印数据
void SLPrint(const SL* psl) //打印
{
assert(psl);
for (int i = 0;i < psl->size;i++)
{
printf("%d -> ", psl->a[i]);
}
printf("\n");
}
4.检查内存容量
如果数据已经填满了内存容量,则需要扩容,一般只有增加数据时需要检查。
void checkcapacity(SL* psl) //检查容量
{
assert(psl);
if (psl->capacity == psl->size)
{
SLDataType* tmp = (SLDataType*)realloc(psl->a, (psl->capacity + 2) * sizeof(SLDataType)); //每次增加两个单位 有可能面临不够的问题
if (tmp == NULL)
{
perror("realloc fail");
return;
}
psl->a = tmp;
psl->capacity += 2;
}
}
每次增加两个数据容量的内存,如果扩容失败会报错。
容量只会增加,所以只有当数据个数等于容量个数时才会实现函数。
5.尾部插入数据
void SLPushBack(SL* psl, SLDataType x)
{
//assert(psl); //尾部插入
//checkcapacity(psl);
//psl->a[psl->size] = x;
//psl->size++;
SLInsert(psl, psl->size, x); //在结尾位置插入x
}
注释的是一般实现方法(下同),SLInsert 为统一的方法。
尾部插入时表示数据已经满了,需要扩容后添加。
6.头部插入数据
void SLPushFront(SL* psl, SLDataType x)
{
//assert(psl); //头部插入
//checkcapacity(psl);
//int end = psl->size - 1;
//while (end >= 0)
//{
// psl->a[end + 1] = psl->a[end];
// --end;
//}
//psl->a[0] = x;
//psl->size++;
SLInsert(psl, 0, x);
}
头部插入数据时需要把后续的数据依次往后移动一个单位。
7.尾部删除
void SLPopBack(SL* psl) //尾部删除
{
/*assert(psl);
if (psl->size == 0)
{
return;
}
psl->size--;*/
SLErase(psl, psl->size-1); //删除psl->size-1 位置的值
}
要避免出现没有数据仍然删除的失误。
8.头部删除
void SLPopFront(SL* psl) //头部删除
{
//assert(psl);
//if (psl->size == 0)
//{
// return;
//}
//for (int i = 0;i < psl->size;i++)
//{
// psl->a[i] = psl->a[i + 1];
//}
//psl->size--;
SLErase(psl, 0);
}
9.查找数据
// 没有找到就返回-1
int SLFind(SL* psl, SLDataType x)
{
assert(psl);
assert(psl->size > 0);
for (int a = 0;a < psl->size;a++)
{
if (psl->a[a] == x)
{
return a;
}
}
return -1;
}
10.任意位置统一的插入数据
// 顺序表在pos位置插入x
void SLInsert(SL* psl, size_t pos, SLDataType x)
{
assert(psl);
checkcapacity(psl);
assert(pos <= psl->size);
size_t end = psl->size;
while (end > pos)
{
psl->a[end ] = psl->a[end - 1];
end--;
}
psl->a[pos] = x;
psl->size++;
}
11.删除任意位置的数据
// 顺序表删除pos位置的值
void SLErase(SL* psl, size_t pos)
{
assert(psl);
assert(psl->size >0);
assert(pos < psl->size);
for (size_t i = pos;i < psl->size -1;i++)
{
psl->a[i] = psl->a[i + 1];
}
psl->size--;
}
12.修改任意位置的数据
// 顺序表修改pos位置的值 改为x
void SLModify(SL* psl, size_t pos, SLDataType x)
{
assert(psl);
assert(psl->size > 0);
assert(pos < psl->size);
psl->a[pos] = x;
}
13.释放内存
void SLDestory(SL* psl) //销毁
{
assert(psl);
free(psl->a);
psl->a = NULL;
psl->size = psl->capacity = 0;
}
14.测试数据
int main()
{
SL s;
SLInit(&s);
SLPrint(&s);
SLPushBack(&s, 1); //尾部插入
SLPushBack(&s, 2);
SLPushBack(&s, 3);
SLPrint(&s);
SLPushFront(&s, 4); //头部插入
SLPushFront(&s, 5);
SLPushFront(&s, 6);
SLPrint(&s);
SLPopBack(&s); //尾部删除
SLPrint(&s);
SLPopFront(&s); //头部删除
SLPrint(&s);
// 顺序表在pos位置插入x
SLInsert(&s, 0, 7);
SLInsert(&s, 2, 8);
SLPrint(&s);
// 顺序表删除pos位置的值
SLErase(&s, 3);
SLPrint(&s);
SLErase(&s,4);
SLPrint(&s);
// 顺序表修改pos位置的值 改为x
SLModify(&s,1, 10);
SLPrint(&s);
SLDestory(&s);
return 0;
}