当前位置:   article > 正文

数据结构之顺序表详解

数据结构之顺序表

计算机科学中,数据结构是处理和组织数据的方法和技术。顺序表是一种常见的线性表数据结构,它基于数组实现,提供了快速的随机访问能力。本文将详细介绍顺序表的定义、特点以及常见操作。

1. 顺序表的定义与特点

顺序表是一种线性表的实现方式,它使用一块连续的内存空间存储元素,并通过下标来访问和操作元素。顺序表具有以下特点:

  1. 连续存储:顺序表使用数组来存储元素,数组中的元素在内存中是连续存储的。
  2. 随机访问:由于元素在内存中连续存储,可以通过下标直接访问任意位置的元素,具有快速的随机访问能力。
  3. 插入和删除的复杂度较高:在顺序表中插入和删除元素时,需要移动其他元素以保持顺序,因此插入和删除的时间复杂度较高。
  4. 固定长度:顺序表的长度是固定的,需要预先分配足够的内存空间来存储元素。

2. 顺序表的操作

2.1 构造顺序表

顺序表在C语言中无法用现有的类型来定义,故需要使用构造类型进行构造出顺序表。

当构造顺序表时,您需要先定义一个结构体来表示顺序表,并分配足够的内存空间来存储元素。

示例代码如下:

  1. #define MAX_SIZE 100 // 宏替换
  2. struct SequentialList {
  3. int data[MAX_SIZE];//MAX_SIZE是一个常量,表示数组空间的大小
  4. int num; // 当前顺序表中的元素个数
  5. int size;//当前所申请数组空间的大小
  6. };

在上面的示例中,我们首先定义了一个结构体 SequentialList,其中包含一个数组 data 用于存储元素,以及一个整型变量 num 表示当前顺序表中的元素个数和size表示数组所能存储的大小。

2.2 创建顺序表

当构造出顺序表结构后,就要创建顺序表,顺序表的创建 即顺序表初始化,示例代码如下:

  1. struct SequentialList * create()
  2. {
  3. //调用malloc函数申请空间
  4. struct SequentialList *p = malloc(sizeof(struct SequentialList));
  5. p->num = 0;//新创建的顺序表元素为0
  6. p->size = MAX_SIZE;//构造中数组的大小
  7. return p;
  8. }

在上述示例中,函数 create() 使用 malloc() 函数为顺序表分配了足够的内存空间,并将其地址赋给指针 p。然后,通过 p->num 将顺序表的元素个数初始化为 0,p->size记录了顺序表中能存储的最大元素个数,并返回指针 p

2.2 判断顺序表是否为空

判断顺序表是否为空可以通过判断顺序表的个数是否为 0 来实现。示例代码如下:

  1. // 判断顺序表是否为空
  2. int isEmpty(struct SequentialList* p) {
  3. return p->num == 0;
  4. }

2.3 判断顺序表是否已满

判断顺序表是否已满可以通过判断个数是否达到最大个数来实现。示例代码如下:

  1. // 判断顺序表是否已满
  2. int isFull(struct SequentialList* p) {
  3. return p->num == p->size;
  4. }

2.4 获取顺序表的长度

获取顺序表的长度即为获取当前顺序表中元素的个数。示例代码如下:

  1. // 获取顺序表的长度
  2. int getLength(struct SequentialList* p) {
  3. return p->num;
  4. }

2.5 在指定位置插入元素

顺序表在进行插入和删除时,复杂度较高,故理解顺序表的插入和删除过程是非常有必要的,在顺序表的指定位置插入元素时,防止因插入而破坏顺序表逻辑结构(线性结构,唯一前驱,唯一后继)需要将插入位置之后的元素依次后移,并将新元素插入到指定位置。故如何移动,是我们要特别注意的,从插入元素的位置开始依次往后移动,那么这样移动就会造成前面所移动的值覆盖后面的值(在未插入前,顺序表是一个接一个的,当插入元素时就会破坏这种结构,要插入位置的空间是已经被占用的,且顺序表空间是连续的,当这个位置向后移动时就会覆盖原来空间的值,从而破坏顺序表结构),这种移动方式是行不通的,那我们要怎么去移动才能保证不会破坏顺序表结构,我们这样找到往后移的位置是没有值(后移位置的空间存在且没有值),通过这样分析我们可以得到顺序表最后一个元素(顺序表数组空间允许下)往后移是不会覆盖顺序表的值,故当顺序表未满时进行插入就需要从顺序表尾开始依次往后移,直到移动到要插入元素位置时进行插入。

顺序表满不进行插入。

 

示例代码如下:

  1. // 在指定位置插入元素
  2. void insert(struct SequentialList* p, int position, int element) {
  3. if (isFull(p)) {
  4. printf("顺序表已满,无法插入元素。\n");
  5. return;
  6. }
  7. if (position < 0 || position > list->size) {
  8. printf("插入位置不合法。\n");
  9. return;
  10. }
  11. // 将插入位置之后的元素后移
  12. for (int i = p->num - 1; i >= position; i--) {
  13. list->data[i + 1] = list->data[i];
  14. }
  15. // 插入新元素
  16. p->data[position] = element;
  17. p->num++;
  18. }

2.6 删除指定位置的元素

删除过程相对于插入过程就要简单一些,删除过程就是将要删除的元素进行覆盖进行,即只要将删除元素的后一个元素前移就可以进行将删除元素覆盖,保证顺序表结构,后面元素也要依次前移。当然顺序表为空不进行删除。即删除顺序表的指定位置元素需要将删除位置之后的元素依次前移,并更新顺序表的长度。

 

示例代码如下:

  1. // 删除指定位置的元素
  2. void delete(struct SequentialList* p, int position) {
  3. if (isEmpty(p)) {
  4. printf("顺序表为空,无法删除元素。\n");
  5. return;
  6. }
  7. if (position < 0 || position >= p->num) {
  8. printf("删除位置不合法。\n");
  9. return;
  10. }
  11. // 将删除位置之后的元素前移
  12. for (int i = position; i < p->num - 1; i++) {
  13. p->data[i] = p->data[i + 1];
  14. }
  15. p->num--;
  16. }

2.7 获取指定位置的元素

获取顺序表的指定位置元素即为通过下标访问对应位置的元素。示例代码如下:

  1. // 获取指定位置的元素
  2. int getElement(struct SequentialList* p, int position) {
  3. if (position < 0 || position >= p->num) {
  4. printf("访问位置不合法。\n");
  5. return -1; // 返回一个特殊值表示出错
  6. }
  7. return p->data[position];
  8. }

2.8遍历顺序表元素

通过循环输出顺序表元素,示例代码如下:

  1. void show(struct SequentialList *p)
  2. {
  3. for(int i = 0;i < p->num;i++)
  4. {
  5. printf("%d ",p->data[i]);
  6. }
  7. printf("\n");
  8. }

总体代码

  1. #define MAX_SIZE 100 // 宏替换
  2. //构造顺序表
  3. struct SequentialList {
  4. int data[MAX_SIZE];//MAX_SIZE是一个常量,表示数组空间的大小
  5. int num; // 当前顺序表中的元素个数
  6. int size;//当前所申请数组空间的大小
  7. };
  8. //创建顺序表
  9. struct SequentialList * create()
  10. {
  11. //调用malloc函数申请空间
  12. struct SequentialList *p = malloc(sizeof(struct SequentialList));
  13. p->num = 0;//新创建的顺序表元素为0
  14. p->size = MAX_SIZE;//构造中数组的大小
  15. return p;
  16. }
  17. // 判断顺序表是否为空
  18. int isEmpty(struct SequentialList* p) {
  19. return p->num == 0;
  20. }
  21. // 判断顺序表是否已满
  22. int isFull(struct SequentialList* p) {
  23. return p->num == p->size;
  24. }
  25. // 获取顺序表的长度
  26. int getLength(struct SequentialList* p) {
  27. return p->num;
  28. }
  29. // 在指定位置插入元素
  30. void insert(struct SequentialList* p, int position, int element) {
  31. if (isFull(p)) {
  32. printf("顺序表已满,无法插入元素。\n");
  33. return;
  34. }
  35. if (position < 0 || position > list->size) {
  36. printf("插入位置不合法。\n");
  37. return;
  38. }
  39. // 将插入位置之后的元素后移
  40. for (int i = p->num - 1; i >= position; i--) {
  41. list->data[i + 1] = list->data[i];
  42. }
  43. // 插入新元素
  44. p->data[position] = element;
  45. p->num++;
  46. }
  47. // 删除指定位置的元素
  48. void delete(struct SequentialList* p, int position) {
  49. if (isEmpty(p)) {
  50. printf("顺序表为空,无法删除元素。\n");
  51. return;
  52. }
  53. if (position < 0 || position >= p->num) {
  54. printf("删除位置不合法。\n");
  55. return;
  56. }
  57. // 将删除位置之后的元素前移
  58. for (int i = position; i < p->num - 1; i++) {
  59. p->data[i] = p->data[i + 1];
  60. }
  61. p->num--;
  62. }
  63. // 获取指定位置的元素
  64. int getElement(struct SequentialList* p, int position) {
  65. if (position < 0 || position >= p->num) {
  66. printf("访问位置不合法。\n");
  67. return -1; // 返回一个特殊值表示出错
  68. }
  69. return p->data[position];
  70. }
  71. //遍历
  72. void show(struct SequentialList *p)
  73. {
  74. for(int i = 0;i < p->num;i++)
  75. {
  76. printf("%d ",p->data[i]);
  77. }
  78. printf("\n");
  79. }
  80. int main() {
  81. struct SequentialList* p = create(); // 创建顺序表并获取指针
  82. // 此时,顺序表已经创建完成,并可以进行操作
  83. // 例如,可以通过 p->data 访问数组,通过 p->length 访问元素个数
  84. for(int i = 1;i < 11;i++)
  85. {
  86. insert(p,i,i);//插入元素(循环插入1-10)
  87. }
  88. show(p);//遍历
  89. delete(p,5);//删除下标为5的元素
  90. show(p);
  91. return 0;
  92. }

3. 总结

顺序表是一种基于数组实现的线性表数据结构,具有快速的随机访问能力。它适用于需要频繁随机访问元素的场景,但插入和删除操作的效率相对较低。通过本文的介绍,您应该对顺序表的定义、特点以及常见操作有了更深入的了解。

希望本文对您理解顺序表有所帮助,感谢您的阅读!

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

闽ICP备14008679号