当前位置:   article > 正文

【数据结构】顺序表详解以及实现(C语言实现)_顺序表的表示与实现

顺序表的表示与实现

 

目录

前言:

顺序表的特点:

 顺序表简介:

 顺序表具体实现:

1.初始化

2.销毁

3.检查空间容量

4.头插和尾插

 5.头删和尾删

6.打印

7.指定位置插入

8.指定位置删除

9. 查找是否有对应元素


顺序表线性表的存储结构,用一组地址连续的存储单元依次存储线性表的数据元素。在顺序表中,在逻辑结构上连续的,物理结构也连续。一般采用数组储存

 顺序表和数组的区别?

顺序表实质上就是对数组的封装,完成了对数组的增删改查的操作。

其实这一张图就能充分解释数组和顺序表的关系


 

前言:

顺序表的特点:

  1. 存储密度高:顺序表的每一个节点都有对应的数据元素,没有额外开销,存储密度高
     
  2. 访问性高:可以通过首地址然后i根据连续性找到后续相应的元素
     
  3. 物理位置相邻:物理位置和逻辑位置一致,保持相邻,但这也意味着插入和删除操作可能涉及到大量元素的移动。

 顺序表简介:

  1. 顺序表分为静态顺序表动态顺序表,静态顺序表在结构体中给的是定长数组,缺点很明显,所以我们主要讨论动态顺序表
     
  2. 动态顺序表主要涉及的内存函数有malloc()和relloc()函数。
     
  3. 动态顺序表主要有初始化,销毁,扩容,头插,尾插,头删,尾删,指定位置插入,查找

 顺序表具体实现:

1.初始化

  1. typedef int SLDataType;
  2. typedef struct SeqList
  3. {
  4. SLDataType* arr;
  5. int size;
  6. int capacity;
  7. }SL;
  8. void SeqListInit(SL* ps)
  9. {
  10. ps->arr = NULL;
  11. ps->size = ps->capacity = 0;
  12. }

我们将arr 的首地址定义成NULL,方便之后增加数据,size表示有效数据,capacity表示当前顺序表容量。

2.销毁

  1. void SeqListDestory(SL* ps)
  2. {
  3. if (ps->arr)
  4. {
  5. free(ps->arr);
  6. }
  7. ps->arr = NULL;
  8. ps->size = ps->capacity = 0;
  9. }

 销毁时,我们先释放顺序表中的数组空间,然后将释放后的指针指向NULL,size和capacity都赋值为0;

3.检查空间容量

  1. void SLCheckCapacity(SL* ps)
  2. {
  3. if (ps->size == ps->capacity)
  4. {
  5. int newcapactity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
  6. SLDataType* tmp = (SLDataType*)realloc(ps->arr, sizeof(ps->capacity));
  7. if (tmp == NULL)
  8. {
  9. perror("realloc fail");
  10. exit(1);
  11. }
  12. ps->arr = tmp;
  13. ps->capacity = newcapactity;
  14. }
  15. }

当size和capacity相等时,说明空间满了,如果在想加入数据,需要进行扩容,这时候就要用到realloc函数了,对现有空间进行扩容,代码意思是申请ps->capacity个字节数的类型为SLDataType*的空间给ps->arr上。

4.头插和尾插

  1. void SeqListPushBack(SL* ps, SLDataType x)//尾插
  2. {
  3. assert(ps);
  4. SLCheckCapacity(ps);
  5. ps->arr[ps->size++] = x;
  6. }//因为size的位置总是在最后一位有效元素的下一个位置的,所以直接插入就好
  7. void SeqListPushFront(SL* ps, SLDataType x)//头插
  8. {
  9. assert(ps);
  10. SLCheckCapacity(ps);
  11. for (int i = ps->size; i > 0; i--)
  12. {
  13. ps->arr[i] = ps->arr[i - 1];
  14. }
  15. ps->arr[0] = x;
  16. ps->size++;
  17. }//头插需要将所有现有元素向后移动一位,在下标为0的元素插入

 5.头删和尾删

  1. void SeqListpopBack(SL* ps, SLDataType x)
  2. {
  3. assert(ps);
  4. SLCheckCapacity(ps);
  5. //ps->arr[ps->size - 1] = -1;
  6. ps->size--;
  7. }//对size直接进行--即可
  8. void SeqListpopFront(SL* ps, SLDataType x)
  9. {
  10. for (int i = ps->size; i > 0; i--)
  11. {
  12. ps->arr[i] = ps->arr[i + 1];
  13. }
  14. ps->size--;
  15. }//头删需要将所有元素向前移动一位即可,有效数据进行--

6.打印

  1. void SeqListprint(SL* ps)
  2. {
  3. for (int i = 0; i < ps->size; i++)
  4. {
  5. printf("%d", ps->arr[i]);
  6. }
  7. printf("\n");
  8. }

7.指定位置插入

  1. void SeqListInsert(SL* ps, int pos, SLDataType x)//顺序表指定位置插入
  2. {
  3. assert(ps);
  4. assert(pos >= 0 && pos <= ps->size);
  5. SLCheckCapacity(ps);
  6. for (int i = ps->size; i > pos; i--)
  7. {
  8. ps->arr[i] = ps->arr[i - 1];
  9. }
  10. ps->arr[pos] = x;
  11. ps->size++;
  12. }//pos位置之后的位置进行向后移动一位,然后再下表为pos位置进行插入

8.指定位置删除

  1. void SeqListErase(SL* ps, int pos)
  2. {
  3. assert(ps);
  4. assert(pos >= 0 && pos <= ps->size);
  5. SLCheckCapacity(ps);
  6. for (int i = ps->size; i < pos; i++)
  7. {
  8. ps->arr[i - 1] = ps->arr[i];
  9. }
  10. ps->size--;
  11. }//pos之后的向前移动一位,将pos位置的值进行覆盖,有效数据-1;

 

9. 查找是否有对应元素

  1. int SeqListFind(SL* ps, SLDataType x)
  2. {
  3. int flag = 1;
  4. assert(ps);
  5. for (int i = 0; i < ps->size; i++)
  6. {
  7. if (ps->arr[i] == x)
  8. {
  9. flag = 0;
  10. return x;
  11. }
  12. }
  13. return -1;
  14. }//遍历顺序表中的所有有效数据,如果与查找的数相等,直接返回查找数,遍历完毕之后,没有发现,返回-1

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/959333
推荐阅读
相关标签
  

闽ICP备14008679号