将顺序表的接口进行详细的实现(干货!!!!!!!!!)详细!!!!!!!

小灰灰 2022-10-29 05:29 127阅读 0赞

在这里插入图片描述

顺序表

顺序表就是用一段连续的物理地址连续的存储单元存放的线性结构.
在这里插入图片描述
动态顺序表:

  1. typedef struct seqList{
  2. SLDataType* _data; //需要进行动态开辟的一个数组
  3. size_t _size; //有效元素的个数
  4. size_t _capacity; //当前我们可以存放的最大元素个数
  5. }seqList; //别名

如果你对这个使用动态存储的结构体,只能看到12个字节,但是对于下面的静态就不一样了,大家可以试一下(很简单,利用sizeof实现)

静态顺序表:

  1. #define N 10
  2. struct seqList2{
  3. SLDataType _data[N];
  4. size_t _size; //有效元素的个数
  5. size_t _capacity; //当前我们可以存放的最大元素个数
  6. }seqList2; //别名

接口声明

  1. //1.初始化
  2. void initSeqList(seqList * sl);
  3. //2.检查内存是否够用
  4. void checkCapacity(seqList* sl);
  5. //3.函数打印
  6. void printSeqList(seqList* ls);
  7. //4.头插
  8. void pushFront(seqList* sl, SLDataType val);
  9. //5.头删
  10. void popFront(seqList* sl);
  11. //6.尾插
  12. void pushBack(seqList* sl, SLDataType val);
  13. //7.尾删
  14. void popBack(seqList* ls);
  15. //8.指定插入
  16. void insert(seqList* sl, int pos, SLDataType val);
  17. //9.指定删除
  18. void erase(seqList* sl, int pos);
  19. //10.查找对应的值
  20. int findIdx(seqList* sl, SLDataType val);
  21. //11.内存大小
  22. int size(seqList* sl);
  23. //12.销毁
  24. void destorySeqList(seqList* sl);

这里有12个对应头文件的声明,量比较多,但是都大体相似,希望能坚持看下去,一起加油!

接口实现

1.初始化
对于初始化这里没有什么要说的,就是将其进行0的赋值就行了.

  1. void initSeqList(seqList * sl){
  2. sl->_data = NULL; //指针指向空间变为0
  3. sl->_size = sl->_capacity = 0; //内存大小和最大容量也变为0,相当于int i=0;操作,很好理解
  4. }

2.检查内存是否够用

  1. void checkCapacity(seqList* sl){
  2. if (sl == NULL) //基本的判断是否为空指针,是则直接返回
  3. return;
  4. if (sl->_size == sl->_capacity){
  5. //在所存储的size和最大的容量相等时,我们就需要扩大内存空间
  6. //当需要扩大内存时,我们的最大容量也需要变化,这里的条件运算符:如果这两个相等则+1,不等开辟二倍的内存
  7. int newCapacity = sl->_capacity == 0 ? 1 : 2 * sl->_capacity;
  8. //写入一个新的指针,进行动态内存的申请
  9. SLDataType* tmp = (SLDataType*)malloc(sizeof(SLDataType)* newCapacity);
  10. //将原始的数据进行拷贝过来
  11. memcpy(tmp, sl->_data, sizeof(SLDataType)*sl->_size);
  12. //释放原有的内存,否则会造成内存泄漏
  13. free(sl->_data);
  14. //更新代码
  15. sl->_data = tmp;
  16. sl->_capacity = newCapacity;
  17. }
  18. }

在这里唯一有点疑惑的可能就是为啥要申请二倍的内存,当两个内存相等的时候,我们只用申请一个,当不等的时候,我们并不能确定要申请多少个空间才能将其覆盖,所以我们直接申请二倍的内存,绝对够用,而且不用不停地进行申请,比较方便.
3.函数打印

  1. void printSeqList(seqList* ls){
  2. for (int i = 0; i < ls->_size; ++i){ //for将内存进行循环
  3. printf("%d ",ls->_data[i]); //然后挨个打印
  4. }
  5. printf("\n");
  6. }

4.头插
在这里插入图片描述

  1. void pushFront(seqList* sl, SLDataType val){
  2. if (sl == NULL)
  3. return; //判断是否空指针
  4. checkCapacity(sl); //内存大小检查
  5. int end = sl->_size; //这里最后一个内存就应该是size的大小,直接利用
  6. while (end > 0){
  7. //在while里面从后往前循环依次将数据往后移一位
  8. sl->_data[end] = sl->_data[end - 1];
  9. --end;
  10. }
  11. sl->_data[0] = val; //将要插入的数据放在最前面
  12. sl->_size++; //更新代码
  13. }

5.头删
在这里插入图片描述

  1. void popFront(seqList* sl){
  2. if (sl == NULL||sl->_size==0)
  3. return;
  4. checkCapacity(sl); //前三行基本操作,不过多解释,后面的话
  5. int start = 1; //第二个变量
  6. while (start < sl->_size){ //循环[2,size)
  7. sl->_data[start-1]=sl->_data[start]; //依次向前一位
  8. ++start; //循环
  9. }
  10. --sl->_size; //更新
  11. }

6.尾插

  1. void pushBack(seqList* sl,SLDataType val){
  2. checkCapacity(sl);
  3. sl->_data[sl->_size] = val; //直接将数据插入到最后
  4. ++sl->_size; //更新
  5. }

7.尾删

  1. void popBack(seqList* ls){
  2. if (ls == NULL)
  3. return;
  4. if (ls->_size > 0) //对于尾删这里并不是真正的删除,而是将size直接-1,从而达到了尾删的效果
  5. ls->_size--;
  6. }

8.指定插入
在这里插入图片描述

  1. void insert(seqList* sl,int pos,SLDataType val){
  2. if (sl == NULL)
  3. return;
  4. if (pos >= 0 && pos <= sl->_size){ //判断输入的位置是否在有效区域
  5. checkCapacity(sl);
  6. int end = sl->_size; //定义最后一个数据
  7. while (end > pos){ //在插入数后面的数据进行循环!!!!!!
  8. sl->_data[end] = sl->_data[end - 1]; //向后移一位
  9. --end; //依次循环
  10. }
  11. sl->_data[pos] = val; //指定位置进行插入
  12. sl->_size++; //更新
  13. }
  14. }

9.指定删除
在这里插入图片描述

  1. void erase(seqList* sl, int pos){
  2. if (sl == NULL || sl->_size == 0)
  3. return;
  4. if (pos >= 0 && pos < sl->_size){ //有效范围内
  5. int start = pos + 1; //定义要插入后面一位的数开始
  6. while (start < sl->_size){ //后面的范围内
  7. sl->_data[start - 1] = sl->_data[start]; //依次向前一格
  8. ++start; //循环
  9. }
  10. --sl->_size; //更新
  11. }
  12. }

10.查找对应的值

  1. int findIdx(seqList* sl, SLDataType val){
  2. int i = 0;
  3. for (; i < sl->_size; ++i){ //内存内循环
  4. if (sl->_data[i] == val) //当值相等的时候
  5. return i; //输出位置
  6. }
  7. return -1; //找不到,返回-1
  8. }

11.内存大小

  1. int size(seqList* sl){
  2. if (sl == NULL)
  3. return 0; //如果为空,返回0
  4. else
  5. return sl->_size; //不为空,返回其长度
  6. }

12.销毁

  1. void destorySeqList(seqList* sl){
  2. if (sl){
  3. if (sl->_data){ //指向空间
  4. free(sl->_data); //空间释放
  5. sl->_data = NULL; //指针变为空
  6. }
  7. }
  8. }

对于顺序表有下面几个特点:
1.空间是连续的
2.支持随机访问
3.空间利用率高
关键:我们一般使用顺序表主要用尾插尾删,因为他们的复杂度低,提高效率,我们还是要多多注重对于内存的理解,这里是比较重要的,对于cpp而言,希望大家能坚持看下来,确实有点长,不积跬步,无以至千里嘛.一起加油!多敲代码!!!

发表评论

表情:
评论列表 (有 0 条评论,127人围观)

还没有评论,来说两句吧...

相关阅读