• 数据结构--顺序表的增删查改--动态分配空间


    一共有两份代码:

    目录

    第一份 分为 两个.c文件和一个.h文件

    1、定义顺序表结构体和宏定义数据类型

    2、顺序表的初始化

    3、顺序表的摧毁(使用完需要摧毁顺序表)

    4、顺序表元素的查找

    5、检查ps的空间是否满了,如果满了则要重新分配空间

    6、在pos位置插入数据

    7、在pos位置删除数据

    8、在头部插入数据

    9、在头部删除数据

    10、在尾部删除数据

    11、在尾部插入数据

    12、代码(全)

    第二份 一个.c文件就可以运行


    第一个分为 两个.c文件和一个.h文件

    1. 说明:
    2. assert(ps)表示如果ps为空,会立即报错,使用这个函数一般要加头文件#include
    3. ps表示SL类型的结构体,相当于顺序表
    4. SeqList.h文件(头文件)存放函数的声明
    5. SeqList.c文件(源文件)存放函数的定义
    6. Seqtext.c存放主函数

    1、定义顺序表结构体和宏定义数据类型

    1. typedef int SLDateType; //数据类型
    2. typedef struct SeqList
    3. {
    4. SLDateType* a; //数据类型指针,指向动态开辟的数组
    5. int size; //顺序表长度
    6. int capacity; //顺序表容量
    7. }SL;

    2、顺序表的初始化

    1. void SLInsert(SL* ps) //顺序表的初始化
    2. {
    3. assert(ps);
    4. ps->a = NULL;
    5. ps->size = 0;
    6. ps->capacity = 0;
    7. }

    3、顺序表的摧毁(使用完需要摧毁顺序表)

    1. void SLDestroy(SL* ps) //顺序表的摧毁
    2. {
    3. assert(ps);
    4. if (ps->a) //如果ps->a不为空
    5. {
    6. free(ps->a);//释放掉pa->a空间
    7. ps->a = NULL;
    8. ps->size = ps->capacity = 0;
    9. }
    10. }

    4、顺序表元素的查找

    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. {
    8. return i;
    9. }
    10. }
    11. return -1;
    12. }

    如果找到了需要找的值,返回值的下标,否者返回-1;

    5、检查ps的空间是否满了,如果满了则要重新分配空间

    1. void SLCheckCapacity(SL*ps)
    2. {
    3. assert(ps);
    4. if (ps->size == ps->capacity)
    5. {
    6. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    7. SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
    8. if (tmp == NULL)
    9. {
    10. perror("realloc fail");
    11. exit(-1);
    12. }
    13. ps->a = tmp;
    14. ps->capacity = newCapacity;
    15. }
    16. }

    刚开始初始化顺序表之后,也通过这个函数分配空间;在这里说一下realloc的作用:

    1.  (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType))表示
    2. 给指向ps->a的指针分配一个大小为newCapacity * sizeof(SLDataType)大小
    3. 的空间,如果在原来指向ps->a的后面的空间被占用了,
    4. 则会异地开辟新的空间,
    5. 并且会拷贝原来的数据过来,而原来的空间会被释放掉。

    6、在pos位置插入数据

    1. //在pos 位置插入x
    2. void SeqListInsert(SeqList* ps, int pos, SLDateType x)
    3. {
    4. assert(ps);
    5. assert(pos>= 0);
    6. assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
    7. SeqListCheckCapacity(ps);
    8. int end = ps->size-1;
    9. while (end>=pos)
    10. {
    11. ps->a[end+1] = ps->a[end];
    12. end--;
    13. }
    14. ps->a[pos] = x;
    15. ps->size++;
    16. }

    在插入数据之前需要考虑顺序表容量有没有满:SEqListCheckCapacity(ps);如果没有满,则将在pos位置往后的数据往后挪,挪完之后再插入数据x;

    7、在pos位置删除数据

    1. //删除pos位置数据
    2. void SLErase(SL* ps, int pos)
    3. {
    4. assert(ps);
    5. assert(pos >= 0);
    6. assert(pos < ps->size);
    7. int begin = pos + 1;
    8. while (begin < ps->size)
    9. {
    10. ps->a[begin - 1] = ps->a[begin];
    11. begin++;
    12. }
    13. ps->size--;
    14. }

    8、在头部插入数据

    1. void SLPushFront(SL* ps, SLDataType x) //头插
    2. {
    3. SLInsert(ps, 0, x);
    4. }

    9、在头部删除数据

    1. void SLPopFront(SL* ps) //头删
    2. {
    3. SLErase(ps, 0);
    4. }

    10、在尾部删除数据

    1. void SLPopBack(SL* ps) //尾删除
    2. {
    3. SLErase(ps, ps->size-1);
    4. }

    11、在尾部插入数据

    1. void SLPushBack(SL* ps, SLDataType x) //尾插入
    2. {
    3. SLInsert(ps, ps->size, x);
    4. }

    12、代码(全)

    这个是.h文件(头文件),用来存放函数的声明和顺序表结构体的定义,引用头文件的时候记得加上#include"SeqList.h"

    1. //SeqList.h
    2. #pragma once
    3. #include
    4. #include
    5. #include
    6. //静态顺序表---不太实用
    7. //N太小了不够用,N大了可能浪费
    8. //#define N 1000
    9. //动态顺序表---按需扩空间
    10. typedef int SLDataType;
    11. typedef struct SeqList
    12. {
    13. SLDataType* a;
    14. int size; //记录存储多少个有效数据
    15. int capacity; //空间容量大小
    16. }SL;
    17. void SLInsert(SL* ps, int pos, SLDataType x);
    18. void SLErase(SL* ps, int pos);
    19. void SLPrint(SL* ps);
    20. void SLInit(SL* ps);
    21. void SLDestroy(SL* ps);
    22. void SLCheckCapacity(SL* ps); //检查容量
    23. //尾插尾删
    24. void SLPushBack(SL* ps, SLDataType x);
    25. void SLPopBack(SL* ps);
    26. //头插头删
    27. void SLPushFront(SL* ps, SLDataType x);
    28. void SLPopFront(SL* ps);
    29. void menu();
    30. int SLFind(SL* ps, SLDataType x, int begin);

     以下是SeqLIst.c文件,存放函数的定义

    1. //SeqList.c
    2. #define _CRT_SECURE_NO_WARNINGS
    3. #pragma once
    4. #include"SeqList.h"
    5. void SLCheckCapacity(SL*ps)
    6. {
    7. assert(ps);
    8. if (ps->size == ps->capacity)
    9. {
    10. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    11. SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
    12. if (tmp == NULL)
    13. {
    14. perror("realloc fail");
    15. exit(-1);
    16. }
    17. ps->a = tmp;
    18. ps->capacity = newCapacity;
    19. }
    20. }
    21. void SLPrint(SL* ps) //打印
    22. {
    23. assert(ps);
    24. for (int i = 0; i < ps->size; ++i)
    25. {
    26. printf(" %d", ps->a[i]);
    27. }
    28. printf("\n");
    29. }
    30. void SLInit(SL* ps) //顺序表的初始化
    31. {
    32. assert(ps);
    33. ps->a = NULL;
    34. ps->size = 0;
    35. ps->capacity = 0;
    36. }
    37. void SLDestroy(SL* ps) //顺序表的摧毁
    38. {
    39. assert(ps);
    40. if (ps->a) //如果ps->a有值在里面
    41. {
    42. free(ps->a);//释放掉pa->a空间
    43. ps->a = NULL;
    44. ps->size = ps->capacity = 0;
    45. }
    46. }
    47. //在pos位置插入数据
    48. void SLInsert(SL *ps,int pos,SLDataType x)
    49. {
    50. assert(ps);
    51. assert(pos >= 0);
    52. assert(pos <= ps->size);
    53. SLCheckCapacity(ps);
    54. int end = ps->size - 1;
    55. while (end >= pos)
    56. {
    57. ps->a[end + 1] = ps->a[end];
    58. end--;
    59. }
    60. ps->a[pos] = x;
    61. ps->size++;
    62. }
    63. //删除pos位置数据
    64. void SLErase(SL* ps, int pos)
    65. {
    66. assert(ps);
    67. assert(pos >= 0);
    68. assert(pos < ps->size);
    69. int begin = pos + 1;
    70. while (begin < ps->size)
    71. {
    72. ps->a[begin - 1] = ps->a[begin];
    73. begin++;
    74. }
    75. ps->size--;
    76. }
    77. void SLPushBack(SL* ps, SLDataType x) //尾插入
    78. {
    79. SLInsert(ps, ps->size, x);
    80. }
    81. void SLPopBack(SL* ps) //尾删除
    82. {
    83. SLErase(ps, ps->size-1);
    84. }
    85. void SLPushFront(SL* ps, SLDataType x) //头插
    86. {
    87. SLInsert(ps, 0, x);
    88. }
    89. void SLPopFront(SL* ps) //头删
    90. {
    91. SLErase(ps, 0);
    92. }
    93. int SLFind(SL* ps, SLDataType x, int begin)
    94. {
    95. assert(ps);
    96. for (int i = begin; i < ps->size; ++i)
    97. {
    98. if (ps->a[i] == x)
    99. {
    100. return i;
    101. }
    102. }
    103. return -1;
    104. }

     以下是用来存放主函数的文件,以及一些函数的调用

    1. //SLtest.c
    2. #define _CRT_SECURE_NO_WARNINGS
    3. #include"SeqList.h"
    4. void menu()
    5. {
    6. printf("***********************************************************\n");
    7. printf("1、尾插数据 2、尾删数据\n");
    8. printf("3、头插数据 4、头删数据\n");
    9. printf("5打印数据 -1退出\n");
    10. printf("***********************************************************\n");
    11. }
    12. int main()
    13. {
    14. SL ps;
    15. SLInit(&ps); //顺序表的初始化
    16. //SLInsert(&ps,0,1);
    17. //SLPrint(&ps);
    18. int n=0;
    19. int option=0;
    20. do
    21. {
    22. menu();
    23. printf("输入操作\n");
    24. scanf("%d", &option);
    25. switch (option)
    26. {
    27. case 1:
    28. printf("请输入你尾插的数据,以-1结束");
    29. scanf("%d",&n);
    30. while (n != -1)
    31. {
    32. SLPushBack(&ps,n);
    33. scanf("%d",&n);
    34. }
    35. break;
    36. case 2:
    37. SLPopBack(&ps);
    38. break;
    39. case 3:
    40. printf("请输入你头插入的数据,以-1结束\n");
    41. scanf("%d", &n);
    42. while (n != -1)
    43. {
    44. SLPushFront(&ps,n);
    45. scanf("%d", &n);
    46. }
    47. break;
    48. case 4:
    49. SLPopFront(&ps);
    50. break;
    51. case 5:
    52. SLPrint(&ps);
    53. break;
    54. default:
    55. break;
    56. }
    57. } while (option != -1);
    58. printf("????\n");
    59. SLDestroy(&ps);
    60. return 0;
    61. }

    第二份 一个.c文件就可以运行

    (将代码复制到.c文件就可以运行)

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #pragma once
    3. #include
    4. #include
    5. #include
    6. typedef int SLDateType;
    7. typedef struct SeqList
    8. {
    9. SLDateType* a;
    10. int size;
    11. int capacity;
    12. }SeqList;
    13. // 对数据的管理:增删查改
    14. void SeqListInit(SeqList* ps);
    15. void SeqListDestroy(SeqList* ps);
    16. void SeqListPrint(SeqList* ps);
    17. void SeqListPushBack(SeqList* ps, SLDateType x);
    18. void SeqListPushFront(SeqList* ps, SLDateType x);
    19. void SeqListPopFront(SeqList* ps);
    20. void SeqListPopBack(SeqList* ps);
    21. // 顺序表查找
    22. int SeqListFind(SeqList* ps, SLDateType x);
    23. // 顺序表在pos位置插入x
    24. void SeqListInsert(SeqList* ps, int pos, SLDateType x);
    25. // 顺序表删除pos位置的值
    26. void SeqListInit(SeqList* ps)//初始化
    27. {
    28. ps->a = NULL;
    29. ps->size = 0;
    30. ps->capacity = 0;
    31. }
    32. void SeqListDestroy(SeqList* ps)
    33. {
    34. assert(ps);
    35. if (ps->a)
    36. {
    37. free(ps->a);
    38. ps->a = NULL; //指针制空,释放
    39. ps->size = ps->capacity = 0;
    40. }
    41. }
    42. void SeqPrint(SeqList* ps) //打印
    43. {
    44. int i;
    45. assert(ps);
    46. for (i = 0; i < ps->size; i++)
    47. {
    48. printf(" %d", ps->a[i]);
    49. }
    50. }
    51. void SeqListCheckCapacity(SeqList* ps) //给ps->a 分配空间或者添加空间
    52. {
    53. assert(ps);
    54. if (ps->size == ps->capacity) //当顺序表长度等于顺序表的容量的时候
    55. {
    56. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    57. SLDateType* temp = (SLDateType*)realloc(ps->a, newCapacity * sizeof(SLDateType));
    58. if (temp == NULL) //if里面用的是"=="
    59. {
    60. printf("realloc failed");
    61. exit(-1);
    62. }
    63. ps->a = temp;
    64. ps->capacity = newCapacity;
    65. }
    66. }
    67. //在pos位置删除数据
    68. void SeqListErase(SeqList* ps, int pos)
    69. {
    70. assert(ps);
    71. assert(pos >= 0);
    72. assert(pos < ps->size);
    73. int begin = pos + 1;
    74. while (begin < ps->size)
    75. {
    76. ps->a[begin--] = ps->a[begin]; //pos位置的数据被它后一位的数据覆盖
    77. begin++;
    78. }
    79. ps->size--;
    80. }
    81. //在pos 位置插入x
    82. void SeqListInsert(SeqList* ps, int pos, SLDateType x)
    83. {
    84. assert(ps);
    85. assert(pos>= 0);
    86. assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
    87. SeqListCheckCapacity(ps);
    88. int end = ps->size-1;
    89. while (end>=pos)
    90. {
    91. ps->a[end+1] = ps->a[end];
    92. end--;
    93. }
    94. ps->a[pos] = x;
    95. ps->size++;
    96. }
    97. void SeqListPushBack(SeqList* ps,SLDateType x) //尾插
    98. {
    99. SeqListInsert(ps, ps->size, x); //相当于在位置ps->a[size]处插入值x
    100. }
    101. void SeqListPopBack(SeqList* ps) //尾删
    102. {
    103. SeqListErase(ps, ps->size - 1);//相当于在位置ps->a[size-1]处删除数据
    104. }
    105. void SeqListPushFront(SeqList* ps, SLDateType x) //头插
    106. {
    107. SeqListInsert(ps, 0, x);
    108. }
    109. void SeqListPopFront(SeqList* ps) //头删
    110. {
    111. SeqListErase(ps, 0);
    112. }
    113. int SeqListFind(SeqList* ps, SLDateType x) //查找元素
    114. {
    115. assert(ps);
    116. for (int i = 0; i < ps->size; ++i)
    117. {
    118. if (ps->a[i] == x)
    119. {
    120. return i; //返回下标
    121. }
    122. }
    123. return -1; //若返回-1则找不到
    124. }
    125. int main()
    126. {
    127. SeqList ps;
    128. int op;
    129. int x;
    130. int find;
    131. SeqListInit(&ps); //初始化
    132. do
    133. {
    134. printf("\n1、尾插 2、尾删 3、头插 4、头删 5、查找元素下标 6、打印 -1、退出\n");
    135. printf("输入你的操作:\n");
    136. scanf("%d", &op);
    137. switch (op)
    138. {
    139. case 1:
    140. printf("请输入你尾删的数据,以-1结束\n");
    141. scanf("%d", &x);
    142. while (x != -1)
    143. {
    144. SeqListPushBack(&ps, x);
    145. scanf("%d", &x);
    146. }
    147. break;
    148. case 2:
    149. SeqListPopBack(&ps); break;
    150. case 3:
    151. printf("请输入你头插的数据,以-1结束\n");
    152. scanf("%d", &x);
    153. while (x != -1)
    154. {
    155. SeqListPushFront(&ps, x);
    156. scanf("%d", &x);
    157. }
    158. break;
    159. case 4:
    160. SeqListPopFront(&ps); break;
    161. case 5:
    162. printf("请输入你要查找的元素x=");
    163. scanf("%d", &x);
    164. if ((find = SeqListFind(&ps, x)) == -1)
    165. {
    166. printf("没有该元素\n");
    167. }
    168. else
    169. printf("下标为%d", SeqListFind(&ps,x));
    170. break;
    171. case 6:
    172. SeqPrint(&ps); break;
    173. default:
    174. break;
    175. }
    176. } while (op != -1);
    177. SeqListDestroy(&ps);
    178. return 0;
    179. }

  • 相关阅读:
    ToBeWritten之基于ATT&CK的模拟攻击:闭环的防御与安全运营
    2022下半年各省软考报名费用汇总,不知道的看这里
    docker开机启动设置
    pytorch初学笔记(一):如何加载数据和Dataset实战
    牛客——OR36 链表的回文结构(C语言,配图,快慢指针)
    只因写了一段爬虫,公司 200 多人被抓!
    AI 智能时代,如何快速搞懂向量数据库库?
    C++——虚函数、虚析构函数、纯虚函数、抽象类
    linux源码安装postgresql以及smlar插件
    REVERSE-COMPETITION-HWS-5TH-2022
  • 原文地址:https://blog.csdn.net/weixin_53269843/article/details/127717044