网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
这一步我们需要创建顺序表并对其进行初始化,
将其 size 置零,capaticy 置为传入参数。
如果想把顺序表中每个数据都初始化为 0 的话可以使用 calloc 函数。
//初始化顺序表
void SeqListInit(SeqList\* ps, size\_t capacity);
void SeqListInit(SeqList\* ps, size\_t capacity)
{
ps->data = (SLDataType\*)malloc(sizeof(SLDataType) \* capacity);
if (ps->data == NULL)
{
perror("SeqListInit");
return;
}
ps->size = 0;
ps->capacity = capacity;
}
顺序表打印
打印顺序表中的数据,
因为顺序表中只有 size 个数据,
所以只需要循环 size 次打印。
void SeqListPrint(SeqList\* ps);
void SeqListPrint(SeqList\* ps)
{
assert(ps->size > 0);
for (int i = 0; i < ps->size; i++)
printf("%d ", ps->data[i]);
printf("\n");
}
检查空间,如果满了,进行增容
后面无论是要尾插、头插还是中间插,
都有可能出现顺序表满的情况,
所以在此之前要进行空间检查,
如果空间存满了就需要扩容。
这里每次将容量扩大为原来的 2 倍,
需要使用 realloc 函数。
扩容之后不要忘了重置 capacity 。
void CheckCapacity(SeqList\* ps);
void CheckCapacity(SeqList\* ps)
{
SLDataType\* tmp = NULL;
if (ps->capacity == ps->size)
tmp = realloc(ps->data, ps->capacity \* 2);
if (tmp != NULL)
ps->data = tmp;
else
return;
ps->capacity \*= 2;
}
顺序表尾插
插入数据之前先判断是否需要扩容。
在顺序表的最后插入一个数据 x ,
由于 size 的值就是现有数据中最后一个数据的下标 +1,
所以直接给 size 位置处的数据赋值。
尾插之后记得 size++ 。
void SeqListPushBack(SeqList\* ps, SLDataType x);
void SeqListPushBack(SeqList\* ps, SLDataType x)
{
CheckCapacity(ps);
ps->data[ps->size] = x;
ps->size++;
}
顺序表尾删
尾删,并不需要我们操作现有的最后一个数据。
因为我们看到的数据是前 size 个,
所以只需要改变 size 就可以减少呈现在我们眼前的数据。
void SeqListPopBack(SeqList\* ps);
void SeqListPopBack(SeqList\* ps)
{
assert(ps->size > 0);
ps->size--;
}
顺序表头插
插入数据之前先判断是否需要扩容。
头插的话后面的数据就要往后移,
从后往前来即可:
然后将空出的位置赋成我们想要的 x 即可。
最后将 size++ 。
void SeqListPushFront(SeqList\* ps, SLDataType x);
void SeqListPushFront(SeqList\* ps, SLDataType x)
{
CheckCapacity(ps);
int end = ps->size - 1;
while (end >= 0)
{
ps->data[end + 1] = ps->data[end];
end--;
}
ps->data[0] = x;
ps->size++;
}
顺序表头删
头删只需要把头上的元素覆盖掉,
覆盖顺序如下:
最后别忘了 size– 。
void SeqListPopFront(SeqList\* ps);
void SeqListPopFront(SeqList\* ps)
{
assert(ps->size > 0);
int start = 1;
while (start < ps->size)
{
ps->data[start - 1] = ps->data[start];
start++;
}
ps->size--;
}
顺序表查找
我们还需要实现在指定位置处插入或删除元素,
这就需要知道指定位置是哪个位置,
所以在此之前先完成查找接口。
只需遍历一遍顺序表,
这里返回的是指定元素第一次出现的位置。
int SeqListFind(SeqList\* ps, SLDataType x);
int SeqListFind(SeqList\* ps, SLDataType x)
{
for (int i = 0; i < ps->size; ++i)
if (ps->data[i] == x)
return i;
return -1;
}
删除指定位置的值
删除指定位置的值,
只需要将指定位置处的数据覆盖掉。
覆盖方式为从前往后走:
最后记得 size– 。
void SeqListErase(SeqList\* ps, size\_t pos);
void SeqListErase(SeqList\* ps, size\_t pos)
{
assert(pos < ps->size);
int start = pos + 1;
while (start < ps->size)
{
ps->a[start - 1] = ps->a[start];
start++;
}
ps->size--;
}
在指定位置插入
插入数据还是要先判断是否需要扩容。
首先将 pos 处及其后部元素向后挪一位,
然后把 pos 处元素赋成 x :
void SeqListInsert(SeqList\* ps, size\_t pos, SLDataType x)
{
assert(pos <= ps->size);
SeqListCheckCapacity(ps);
int end = ps->size - 1;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
顺序表销毁
由于顺序表是动态开辟来的,
所以程序结束时一定要将空间释放,
以免造成内存泄漏。
void SeqListDestory(SeqList\* ps);
void SeqListDestory(SeqList\* ps)
{
free(ps->data);
ps->data = NULL;
ps->capacity = 0;
ps->size = 0;
}
总结
对于顺序表,很明显它是连续存放数据的,且支持随机访问,可以直接访问任意位置处的数据。
但是,每次头插或指定位置插入、删除元素都需要遍历数组,时间复杂度为 O(N),效率较低。
此外,这里动态增容一次增加原来的一倍,当数据量很大的时候,增容占用的空间也会更多,而如果剩余数据很少,那同样会造成大量空间的浪费。
完整代码
SeqList.h
将有关变量、符号及函数的声明、头文件的引用放在头文件中:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
typedef struct SeqList
{
SLDataType\* data;
int size;
int capacity;
}SeqList;
//初始化顺序表
void SeqListInit(SeqList\* ps, size\_t capacity);
// 顺序表打印
void SeqListPrint(SeqList\* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList\* ps);


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
rint(SeqList\* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList\* ps);
[外链图片转存中...(img-CtQB2lRi-1715591696309)]
[外链图片转存中...(img-ChDg04EK-1715591696310)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**