深圳幻海软件技术有限公司 欢迎您!

数据结构—顺序表

2023-04-22

目录1.顺序表概念2.顺序表分类:3.实现动态顺序表   3.1初始化顺序表 SLInit   3.2检查顺序表容量  SLCheckCapacity    3.3打印顺

目录

1.顺序表概念

2.顺序表分类:

3.实现动态顺序表

      3.1初始化顺序表  SLInit

      3.2 检查顺序表容量   SLCheckCapacity

      3.3 打印顺序表  SLPrint

      3.4尾插 SLPushBack

      3.5头插 SLPushFront

      3.6尾删 SLPopback

      3.7头删  SLPopFront 

      3.8 顺序表查找 SLFind 

      3.9  顺序表修改 SLModify

  4. 顺序表总结

       4.1 顺序表优化

       4.2 顺序表的缺点


1.顺序表概念

       顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组 上完成数据的增删查改


2.顺序表分类:

   2.1 静态顺序表:使用定长数组存储元素。(不实用)

   2.2动态顺序表:使用动态开辟的数组存储。


3.实现动态顺序表

      3.1 初始化顺序表  SLInit

  1. void SLInit(SL* ps)
  2. {
  3. assert(ps != NULL);
  4. ps->a = NULL;
  5. ps->size = ps->capacity = 0;
  6. }

      3.2 检查顺序表容量   SLCheckCapacity

  1. void SLCheckCapacity(SL* ps)
  2. {
  3. assert(ps != NULL);
  4. // 检查容量空间,满了扩容
  5. if (ps->size == ps->capacity)
  6. {
  7. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
  8. SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
  9. if (tmp == NULL)
  10. {
  11. printf("realloc fail\n");
  12. //exit(-1);
  13. return;
  14. }
  15. ps->a = tmp;
  16. ps->capacity = newCapacity;
  17. }
  18. }

       3.3 打印顺序表  SLPrint

  1. void SLPrint(SL* ps)
  2. {
  3. assert(ps != NULL);
  4. //assert(ps);
  5. for (int i = 0; i < ps->size; ++i)
  6. {
  7. printf("%d ", ps->a[i]);
  8. }
  9. printf("\n");
  10. }

       3.4 尾插 SLPushBack

  1. void SLPushBack(SL* ps, SLDataType x)
  2. {
  3. assert(ps != NULL);
  4. SLCheckCapacity(ps);
  5. ps->a[ps->size] = x;
  6. ps->size++;
  7. //SLInsert(ps, ps->size, x);
  8. }

    3.5 头插 SLPushFront

  1. void SLPushFront(SL* ps, SLDataType x)
  2. {
  3. assert(ps != NULL);
  4. SLCheckCapacity(ps);
  5. // 挪动数据
  6. int end = ps->size - 1;
  7. while (end >= 0)
  8. {
  9. ps->a[end + 1] = ps->a[end];
  10. --end;
  11. }
  12. ps->a[0] = x;
  13. ps->size++;
  14. //SLInsert(ps, 0, x);
  15. }

   3.6 尾删 SLPopback

  1. void SLPopBack(SL* ps)
  2. {
  3. assert(ps->size > 0);//暴力检查,顺序表为空不能删
  4. ps->size--;
  5. }

   3.7 头删  SLPopFront 

  1. void SLPopFront(SL* ps)
  2. {
  3. assert(ps != NULL);
  4. assert(ps->size > 0);
  5. int begin = 1;
  6. while (begin < ps->size)
  7. {
  8. ps->a[begin - 1] = ps->a[begin];
  9. ++begin;
  10. }
  11. ps->size--;
  12. //SLErase(ps, 0);
  13. }

  3.8 顺序表查找 SLFind 

  1. int SLFind(SL* ps, SLDataType x)
  2. {
  3. assert(ps);
  4. for (int i = 0; i < ps->size; ++i)
  5. {
  6. if (ps->a[i] == x)
  7. return i;
  8. }
  9. return -1;
  10. }

  3.9  顺序表修改 SLModify

  1. void SLModify(SL* ps, int pos, SLDataType x)
  2. {
  3. assert(ps);
  4. assert(pos >= 0 && pos < ps->size);
  5. ps->a[pos] = x;
  6. }

  4. 顺序表总结

       4.1 顺序表优化

       使用SLInsert函数实现 尾插,头插

       使用SLErase函数实现 尾删,头删

  1. void SLInsert(SL* ps, int pos, SLDataType x)
  2. {
  3. assert(ps);
  4. assert(pos >= 0 && pos <= ps->size);
  5. SLCheckCapacity(ps);
  6. // 挪动数据
  7. int end = ps->size - 1;
  8. while (end >= pos)
  9. {
  10. ps->a[end + 1] = ps->a[end];
  11. --end;
  12. }
  13. ps->a[pos] = x;
  14. ps->size++;
  15. }
  1. void SLErase(SL* ps, int pos)
  2. {
  3. assert(ps);
  4. assert(pos >= 0 && pos < ps->size);
  5. //两种方法实现
  6. //int begin = pos;
  7. //while (begin < ps->size-1)
  8. //{
  9. //ps->a[begin] = ps->a[begin + 1];
  10. //++begin;
  11. //}
  12. int begin = pos + 1;
  13. while (begin < ps->size)
  14. {
  15. ps->a[begin - 1] = ps->a[begin];
  16. ++begin;
  17. }
  18. ps->size--;
  19. }

 4.2 顺序表的缺点

   由于头插和头删需要移动数据,所以时间复杂度为O(N),所以后面引入链表实现。

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览44726 人正在系统学习中