当前位置:   article > 正文

关于顺序表的基本操作(c语言)_一、完成顺序表的初始化、建立、查找(按位置和按值)、插入(指定在表的第i位置)、

一、完成顺序表的初始化、建立、查找(按位置和按值)、插入(指定在表的第i位置)、

一.简介:

顺序表是C语言中的一种数据结构,它通常基于数组实现。顺序表允许我们在连续内存区域上保存线性数据,并且支持快速的随机访问。

通常情况下,顺序表具有以下特点:

*长度固定:一旦创建,其长度就不可以改变。

*支持随机访问:我们可以使用下标(索引)获取指定位置的元素。

*适合静态数据存储:对于只需要在运行时读取而无需修改的数据集合,如静态配置信息等,使用  顺序表非常方便和高效。

由于顺序表在内部实现上通常是一个数组,在进行插入、删除等操作时可能需要进行大量的数据移动,因此,对于需要频繁地增删数据的情况,顺序表性能会受到影响。此时,链表可能更适合用来存储和操作动态数据。后续会再跟新链表的基本操作。

二.顺序表的定义与基本操作

值得注意的是,由于我们使用的是c语言,所以预处理需要做一些处理,比如我们需要以下头文件

代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>

其中有了#include<stdlib.h>,我们才可以malloc和free

有了#include<stdbool.h>,我们才可以使用bool

我将介绍一下顺序表的结构体定义,顺序表的静态存储与动态存储,并基于动态存储解释顺序表的基本操作。以下是我将介绍的基本操作的函数声明,结尾我会放入完整代码。(过程如有错误,请指出,虚心学习,学无止境!)

代码如下:

  1. void InitList(SeqList* L);
  2. void DestroyList(SeqList* L);
  3. int GetElem(SeqList L,int i);
  4. int LocateElem(SeqList L,int e);
  5. bool ListInsert(SeqList* L,int i,int e);
  6. bool ListDelete(SeqList* L,int i,int* e);
  7. void IncreaseSize(SeqList* L,int len);
  8. bool Empty(SeqList L);
  9. void PrintList(SeqList);
  10. int Length(SeqList L);

1.实现顺序表的结构体定义:

顺序表的静态存储结构体定义:

代码如下:

  1. #define Maxsize 10
  2. typedef struct {
  3. int data[Maxsize];
  4. int length;
  5. } SqList;
  6. SqList L;

以上为顺序表的静态存储,通常我们更倾向于使用顺序表的动态存储,因为动态存储在顺序表的容量不够时可以增加容量,而静态存储在定义的那一刻就已经固定了容量,无法再更改。

顺序表的动态存储结构体定义:

代码如下:

  1. typedef struct
  2. {
  3. int* data;
  4. int length;
  5. int maxsize;
  6. }SeqList;

由于动态存储更广泛使用,所以接下来的基本操作基于顺序表的动态存储来进行解释说明。

2.初始化

代码如下:

  1. void InitList(SeqList* L)
  2. {
  3. L->data=(int*)malloc(sizeof(int)*Maxsize);
  4. L->length=0;
  5. L->maxsize=Maxsize;
  6. }

 3.销毁

代码如下:

  1. void DestroyList(SeqList* L)
  2. {
  3. free(L->data);
  4. L->data=NULL;
  5. L->length=0;
  6. L->maxsize=0;
  7. }

4.查找

查找分为两种,一种是通过给定的位序得到顺序表中该位置的数据,一种是通过给定的数据得到顺序表中该数据的位置,注意不要混淆。此外,读者还要明白位序和顺序表中下标的区别,位序是从1开始算起,而顺序表中的下标是从0开始算起,要分辨清楚哦。

第一种:通过给定位序查找表中元素

代码如下:

  1. int GetElem(SeqList L,int i)
  2. {
  3. if(i<1||i>L.length)
  4. return 0;
  5. return L.data[i-1];
  6. }

给定的位序如果是小于1或者大于表长,那便是无效数据,返回0;

反之,则返回表中数据,注意返回的是i-1,理由开头解释过了。

同时,为什么这个函数我们是用的int类型而不是bool类型呢?因为我们要返回的数据类型是int

我们开始的定义中,Elemtype(定义的数据类型)为int,为了返回数据,我们的函数定义为int,如果没有返回数据,也即失败了,我们便返回0,返回0的意思便是返回失败。

第二种:通过给定值查找表中等于该值的数据的位置

代码如下:

  1. int LocateElem(SeqList L,int e)
  2. {
  3. for(int i=0;i<L.length;i++)
  4. {
  5. if(L.data[i]==e)
  6. return i+1;
  7. }
  8. return 0;
  9. }

我们通过遍历,直到遍历到元素中的数据的值为给定的数据值,直接返回i+1,也即该元素在表中的下标+1,返回的是位序,否则的话没有相应元素,我们返回0代表返回失败。

同时我们要注意,在for循环里定义i这个操作是c99才可以使用的操作,如果是非c99,我们在外面定义int i,再把i放到for循环里令i=0即可。

5.插入

插入操作我们不但要注意位序和下标的区别,

同时还要留意:插入的时候,是从表尾开始各个元素往后移动一位;删除的时候,是从删除位置开始各个元素往前移动一位。这是一个小细节。

代码如下:

  1. bool ListInsert(SeqList* L,int i,int e)
  2. {
  3. if(i<1||i<L->length+1)
  4. return false;
  5. if(L->length>=L->maxsize)
  6. return false;
  7. for(int j=L->length;j>=i;j--)
  8. L->data[j]=L->data[j-1];
  9. L->data[i-1]=e;
  10. L->length++;
  11. return true;
  12. }

如果给定的位序小于零或者大于表长+1,则返回false。

这里为什么是表长+1呢?是因为我们在进行插入操作的时候,插入之后的位置我们都是要往后移动的,表尾一样要往后移动一位,此时表长+1。

同时,如果此时表长超过了表的最大容量的话,我们没有多余容量再进行插入操作,此时的情况也是false。如果上述的情况都不是的话,则我们可以进行遍历来将表中的元素从表尾开始往后移动一位,具体操作便是将前一个元素赋值给后一个元素。

接着便是插入位置赋值e,表长+1,返回true。

6.删除

代码如下:

  1. bool ListDelete(SeqList* L,int i,int* e)
  2. {
  3. if(i<1||i>L->length)
  4. return false;
  5. *e=L->data[i-1];
  6. for(int j=i;j<L->length;j++)
  7. L->data[j-1]=L->data[j];
  8. L->length--;
  9. return true;
  10. }

这里无需length+1,要注意的是e是返回删除的元素值,所以这里的e是传入的int*类型

7.扩容

代码如下:

  1. void IncreaseSize(SeqList* L,int len)
  2. {
  3. int* p=L->data;
  4. L->data=(int*)malloc(sizeof(int)*(len+L->maxsize));
  5. for(int i=0;i<L->length;i++)
  6. L->data[i]=p[i];
  7. L->maxsize+=len;
  8. free(p);
  9. }

通过定义指针p指向L->data,旨在保存原有的数据。

然后对L->data重新动态分配得到扩容后的内存空间。

接着通过遍历赋值原有的数据并修改表的最大容量。

最后注意要释放指针p的内存空间。

8.判空

代码如下:

  1. bool Empty(SeqList L)
  2. {
  3. return (L.length==0);
  4. }

代码效果等同于:

  1. bool Empty(SeqList L)
  2. {
  3. if (L.length==0)
  4. return true;
  5. else
  6. return false;
  7. }

9.遍历输出

代码如下:

  1. void PrintList(SeqList L)
  2. {
  3. for(int i=0;i<L.length;i++)
  4. printf("L.data[%d]=%d\n",i,L.data[i]);
  5. }

10.返回表长

代码如下:

  1. int Length(SeqList L)
  2. {
  3. return L.length;
  4. }

三.完整代码

代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #define Maxsize 10
  5. typedef struct
  6. {
  7. int* data;
  8. int length;
  9. int maxsize;
  10. }SeqList;
  11. void InitList(SeqList* L);
  12. void DestroyList(SeqList* L);
  13. int GetElem(SeqList L,int i);
  14. int LocateElem(SeqList L,int e);
  15. bool ListInsert(SeqList* L,int i,int e);
  16. bool ListDelete(SeqList* L,int i,int* e);
  17. void IncreaseSize(SeqList* L,int len);
  18. bool Empty(SeqList L);
  19. void PrintList(SeqList);
  20. int Length(SeqList L);
  21. int main()
  22. {
  23. return 0;
  24. }
  25. void InitList(SeqList* L)
  26. {
  27. L->data=(int*)malloc(sizeof(int)*Maxsize);
  28. L->length=0;
  29. L->maxsize=Maxsize;
  30. }
  31. void DestroyList(SeqList* L)
  32. {
  33. free(L->data);
  34. L->data=NULL;
  35. L->length=0;
  36. L->maxsize=0;
  37. }
  38. int GetElem(SeqList L,int i)
  39. {
  40. if(i<1||i>L.length)
  41. return 0;
  42. return L.data[i-1];
  43. }
  44. int LocateElem(SeqList L,int e)
  45. {
  46. for(int i=0;i<L.length;i++)
  47. {
  48. if(L.data[i]==e)
  49. return i+1;
  50. }
  51. return 0;
  52. }
  53. bool ListInsert(SeqList* L,int i,int e)
  54. {
  55. if(i<1||i<L->length+1)
  56. return false;
  57. if(L->length>=L->maxsize)
  58. return false;
  59. for(int j=L->length;j>=i;j--)
  60. L->data[j]=L->data[j-1];
  61. L->data[i-1]=e;
  62. L->length++;
  63. return true;
  64. }
  65. bool ListDelete(SeqList* L,int i,int* e)
  66. {
  67. if(i<1||i>L->length)
  68. return false;
  69. *e=L->data[i-1];
  70. for(int j=i;j<L->length;j++)
  71. L->data[j-1]=L->data[j];
  72. L->length--;
  73. return true;
  74. }
  75. void IncreaseSize(SeqList* L,int len)
  76. {
  77. int* p=L->data;
  78. L->data=(int*)malloc(sizeof(int)*(len+L->maxsize));
  79. for(int i=0;i<L->length;i++)
  80. L->data[i]=p[i];
  81. L->maxsize+=len;
  82. free(p);
  83. }
  84. bool Empty(SeqList L)
  85. {
  86. return (L.length==0);
  87. }
  88. void PrintList(SeqList L)
  89. {
  90. for(int i=0;i<L.length;i++)
  91. printf("L.data[%d]=%d\n",i,L.data[i]);
  92. }
  93. int Length(SeqList L)
  94. {
  95. return L.length;
  96. }

作者也是考研生,会陆续更新接下来数据结构的代码内容,希望能给广大考研生提供帮助,如有错误,欢迎指出,一起进步!纯手打干货,写文章不易,喜欢的点赞,觉得有用的收藏,点个关注,大家的点赞、收藏、关注便是作者持续更新分享的动力!

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

闽ICP备14008679号