当前位置:   article > 正文

数据结构-顺序表基本操作的实现(含全部代码)_顺序表的基本操作代码

顺序表的基本操作代码

今天起开始编写数据结构中的各种数据结构及其算法的实现。

主要依据严蔚敏版数据结构教材以及王道数据结构考研辅导书。

今天是线性表中的顺序表的实现,主要实现函数如下,读者有需要可以评论,我可以适当加几个。

  • CreateList(SqList &L,int n) 参数:顺序表L,顺序表长度n 功能:创建长度为的顺序表 时间复杂度:O(n)
  • InitList(SqList &L) 参数:顺序表L 功能:初始化 时间复杂度:O(1)
  • InsertList(SqList &L,int i,ElemType e) 参数:顺序表L,位置i,元素e 功能:位置i处插入元素e 时间复杂度:O(n)
  • ListDelete(SqList &L,int i) 参数:顺序表L,位置i 功能:删除位置i处元素 时间复杂度:O(n)
  • LocateElem(SqList L,ElemType e) 参数:顺序表L,元素e 功能:返回第一个等于e的元素的位置 时间复杂度:O(n)
  • Reverse(SqList &L) 参数:顺序表L 倒置函数 将原顺序表直接倒置
  • PrintList(SqList L) 参数:顺序表L 功能:遍历L,并输出
  • SplitSort(SqList &L) 参数:顺序表L 功能:分开奇偶,并分开排序
  • ClearList(SqList &L) 参数:顺序表L 功能:清空顺序表

代码如下:

  1. /*
  2. Project: sequence_list(数据结构-顺序表)
  3. Date: 2018/09/12 20191012修改 添加Reverse 20200819修改 添加ClearList
  4. Author: Frank Yu
  5. CreateList(SqList &L,int n) 参数:顺序表L,顺序表长度n 功能:创建长度为的顺序表 时间复杂度:O(n)
  6. InitList(SqList &L) 参数:顺序表L 功能:初始化 时间复杂度:O(1)
  7. InsertList(SqList &L,int i,ElemType e) 参数:顺序表L,位置i,元素e 功能:位置i处插入元素e 时间复杂度:O(n)
  8. ListDelete(SqList &L,int i) 参数:顺序表L,位置i 功能:删除位置i处元素 时间复杂度:O(n)
  9. LocateElem(SqList L,ElemType e) 参数:顺序表L,元素e 功能:返回第一个等于e的元素的位置 时间复杂度:O(n)
  10. Reverse(SqList &L) 参数:顺序表L 倒置函数 将原顺序表直接倒置
  11. PrintList(SqList L) 参数:顺序表L 功能:遍历L,并输出
  12. SplitSort(SqList &L) 参数:顺序表L 功能:分开奇偶,并分开排序
  13. ClearList(SqList &L) 参数:顺序表L 功能:清空顺序表
  14. */
  15. #include<cstdio>
  16. #include<cstdlib>
  17. #include<cstring>
  18. #include<cmath>
  19. #include<algorithm>
  20. #include<iostream>
  21. #define MaxSize 100
  22. #define ElemType int
  23. #define Status int
  24. using namespace std;
  25. //顺序表数据结构
  26. typedef struct
  27. {
  28. ElemType data[MaxSize];//顺序表元素
  29. int length; //顺序表当前长度
  30. }SqList;
  31. //***************************基本操作函数*******************************//
  32. //初始化顺序表函数,构造一个空的顺序表
  33. Status InitList(SqList &L)
  34. {
  35. memset(L.data, 0, sizeof(L));//初始化数据为0
  36. L.length = 0; //初始化长度为0
  37. return 0;
  38. }
  39. //创建顺序表函数 初始化前n个数据
  40. bool CreateList(SqList &L, int n)
  41. {
  42. if (n<0 || n>MaxSize)false;//n非法
  43. for (int i = 0; i<n; i++)
  44. {
  45. scanf("%d", &L.data[i]);
  46. L.length++;
  47. }
  48. return true;
  49. }
  50. //插入函数 位置i插入数据 i及之后元素后移 1=<i<=length+1
  51. bool InsertList(SqList &L, int i, ElemType e)
  52. {
  53. if (i<1 || i>L.length + 1) //判断位置是否有效
  54. {
  55. printf("位置无效!!!\n");
  56. return false;
  57. }
  58. if (L.length >= MaxSize)//判断存储空间是否已满
  59. {
  60. printf("当前存储空间已满!!!\n");
  61. return false;
  62. }
  63. for (int j = L.length; j >= i; j--)//位置i及之后元素后移
  64. {
  65. L.data[j] = L.data[j - 1];
  66. }
  67. L.data[i - 1] = e;
  68. L.length++;
  69. return true;
  70. }
  71. //删除函数 删除位置i的元素 i之后的元素依次前移
  72. bool ListDelete(SqList &L, int i)
  73. {
  74. if (i<1 || i>L.length)
  75. {
  76. printf("位置无效!!!\n");
  77. return false;
  78. }
  79. for (int j = i; j <= L.length - 1; j++)//位置i之后元素依次前移覆盖
  80. {
  81. L.data[j - 1] = L.data[j];
  82. }
  83. L.length--;
  84. return true;
  85. }
  86. //查找函数 按位置从小到大查找第一个值等于e的元素 并返回位置
  87. int LocateElem(SqList L, ElemType e)
  88. {
  89. for (int i = 0; i<L.length; i++)//从低位置查找
  90. {
  91. if (L.data[i] == e)
  92. return i + 1;
  93. }
  94. return 0;
  95. }
  96. //倒置函数 将原顺序表直接倒置
  97. void Reverse(SqList &L)
  98. {
  99. if (L.length)
  100. for (int i = 0; i<L.length - 1 - i; i++)
  101. {
  102. int t = L.data[i];
  103. L.data[i] = L.data[L.length - 1 - i];
  104. L.data[L.length - 1 - i] = t;
  105. }
  106. }
  107. //奇偶分开并排序
  108. void SplitSort(SqList &L)
  109. {
  110. int Even = 0;
  111. int Odd = L.length - 1;
  112. int i = 0;
  113. int j = L.length - 1;
  114. bool flag = false; // 交换标志
  115. if (L.length)
  116. for (; i < j; i++, j--)
  117. {
  118. while (L.data[i] % 2 != 0 && i<L.length - 1)i++;
  119. while (L.data[j] % 2 == 0 && j>0)j--;
  120. if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0 && i<j)
  121. {
  122. int temp = L.data[i];
  123. L.data[i] = L.data[j];
  124. L.data[j] = temp;
  125. flag = true;
  126. }
  127. if (!flag) //没有交换
  128. {
  129. if (i > j) { // 恰好奇偶分开
  130. Even = j;
  131. Odd = i;
  132. }
  133. else {
  134. Even = L.length - 1;//全奇数
  135. Odd = 0; //全偶数
  136. }
  137. }
  138. }
  139. if (flag)//有交换
  140. {
  141. for (int i = 0; i<L.length; i++)
  142. if (L.data[i] % 2 == 0)
  143. {
  144. Odd = i;
  145. Even = i - 1;
  146. break;
  147. }
  148. }
  149. sort(L.data, L.data + Even + 1);
  150. sort(L.data + Odd, L.data + L.length);
  151. }
  152. //清空顺序表
  153. void ClearList(SqList &L) {
  154. L.length = 0;
  155. }
  156. //********************************功能函数*****************************************//
  157. //输出功能函数 按位置从小到大输出顺序表所有元素
  158. void PrintList(SqList L)
  159. {
  160. printf("当前顺序表所有元素:");
  161. for (int i = 0; i<L.length; i++)
  162. {
  163. printf("%d ", L.data[i]);
  164. }
  165. printf("\n");
  166. }
  167. //创建顺序表函数
  168. void Create(SqList &L)
  169. {
  170. int n; bool flag;
  171. L.length = 0;
  172. printf("请输入要创建的顺序表长度(>1):");
  173. scanf("%d", &n);
  174. printf("请输入%d个数(空格隔开):", n);
  175. flag = CreateList(L, n);
  176. if (flag) {
  177. printf("创建成功!\n");
  178. PrintList(L);
  179. }
  180. else printf("输入长度非法!\n");
  181. }
  182. //插入功能函数 调用InsertList完成顺序表元素插入 调用PrintList函数显示插入成功后的结果
  183. void Insert(SqList &L)
  184. {
  185. int place; ElemType e; bool flag;
  186. printf("请输入要插入的位置(从1开始)及元素:\n");
  187. scanf("%d%d", &place, &e);
  188. flag = InsertList(L, place, e);
  189. if (flag)
  190. {
  191. printf("插入成功!!!\n");
  192. PrintList(L);
  193. }
  194. }
  195. //删除功能函数 调用ListDelete函数完成顺序表的删除 调用PrintList函数显示插入成功后的结果
  196. void Delete(SqList &L)
  197. {
  198. int place; bool flag;
  199. printf("请输入要删除的位置(从1开始):\n");
  200. scanf("%d", &place);
  201. flag = ListDelete(L, place);
  202. if (flag)
  203. {
  204. printf("删除成功!!!\n");
  205. PrintList(L);
  206. }
  207. }
  208. //查找功能函数 调用LocateElem查找元素
  209. void Search(SqList L)
  210. {
  211. ElemType e; int flag;
  212. printf("请输入要查找的值:\n");
  213. scanf("%d", &e);
  214. flag = LocateElem(L, e);
  215. if (flag)
  216. {
  217. printf("该元素位置为:%d\n", flag);
  218. }
  219. else
  220. printf("未找到该元素!\n");
  221. }
  222. //菜单
  223. void menu()
  224. {
  225. printf("********1.创建 2.插入*********\n");
  226. printf("********3.删除 4.查找*********\n");
  227. printf("********5.倒置 6.分奇偶排序***\n");
  228. printf("********7.输出 8.清空*********\n");
  229. printf("********9.退出 *********\n");
  230. }
  231. int main()
  232. {
  233. SqList L; int choice;
  234. InitList(L);
  235. while (1)
  236. {
  237. menu();
  238. printf("请输入菜单序号:\n");
  239. scanf("%d", &choice);
  240. if (9 == choice) break;
  241. switch (choice)
  242. {
  243. case 1:Create(L); break;
  244. case 2:Insert(L); break;
  245. case 3:Delete(L); break;
  246. case 4:Search(L); break;
  247. case 5:Reverse(L); break;
  248. case 6:SplitSort(L); break;
  249. case 7:PrintList(L); break;
  250. case 8:ClearList(L); break;
  251. default:printf("输入错误!!!\n");
  252. }
  253. }
  254. return 0;
  255. }

结果截图:

插入结果截图
删除结果截图
查找结果截图
输出结果截图

---------------------------------------------2018-09-18更新 添加创建函数 菜单有改动-----------------------------------------

                                                                 

---------------------------------------------20191012更新 添加Reverse函数--------------------------------------------

根据下方评论,添加了倒置函数,参考stl的Reverse写法

  1. template <class _RandomAccessIter>
  2. _STLP_INLINE_LOOP void
  3. __reverse(_RandomAccessIter __first, _RandomAccessIter __last, const random_access_iterator_tag &) {
  4. for (; __first < __last; ++__first)
  5. _STLP_STD::iter_swap(__first, --__last);
  6. }
倒置展示

2019年10月23日更新,应评论区小伙伴的要求,添加了奇偶分开,并排序的函数

  1. //奇偶分开并排序 前奇数 后偶数
  2. void SplitSort(SqList &L)
  3. {
  4. int Even = 0;
  5. int Odd = L.length - 1;
  6. int i = 0;
  7. int j = L.length - 1;
  8. bool flag = false; // 交换标志
  9. if (L.length)
  10. for (; i < j; i++, j--)
  11. {
  12. while (L.data[i] % 2 != 0 && i<L.length - 1)i++;
  13. while (L.data[j] % 2 == 0 && j>0)j--;
  14. if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0 && i<j)
  15. {
  16. int temp = L.data[i];
  17. L.data[i] = L.data[j];
  18. L.data[j] = temp;
  19. flag = true;
  20. }
  21. if (!flag) //没有交换
  22. {
  23. if (i > j) { // 恰好奇偶分开
  24. Even = j;
  25. Odd = i;
  26. }
  27. else {
  28. Even = L.length - 1;//全奇数
  29. Odd = 0; //全偶数
  30. }
  31. }
  32. }
  33. if (flag)//有交换
  34. {
  35. for (int i = 0; i<L.length; i++)
  36. if (L.data[i] % 2 == 0)
  37. {
  38. Odd = i;
  39. Even = i - 1;
  40. break;
  41. }
  42. }
  43. sort(L.data, L.data + Even + 1);
  44. sort(L.data + Odd, L.data + L.length);
  45. }
测试全奇偶

有奇偶

代码已更新至上方全部代码!!!

------20211201修改-------

感谢@Cendrillon_提出的bug,上方代码已修改。之前未考虑到没有交换可能是恰好奇偶分开的情况。

------20211201修改-------

-------------------------20200819修改 添加ClearList-------------------------------------

代码由评论区用户__BlackHole提供,已更新至上方全部代码。

至于销毁,我是使用的静态分配,如果是new(delete释放)或malloc(free释放)的话,需要释放空间,其实就是堆和栈的区别。

堆和栈的区别就是申请方式不同:栈是系统自动分配空间,而堆则是程序员根据需要申请空间。由于栈上的空间是自动分配自动回收的,所以,栈内数据的生存周期只是在函数的运行过程中,运行后就释放掉。而堆上的数据只要程序员不释放空间,就一直可以访问到,缺点是一旦忘记释放会造成内存泄露。

综上,我写的顺序表不需要进行销毁,当然,顺序表最大长度也固定了,各有利弊,如果是动态分配的话记得释放空间呀!

关注博主公众号,回复 数据结构资源 获取数据结构(C语言版)、数据结构(第二版)课件、所有算法代码。

更多数据结构与算法的实现:数据结构(严蔚敏版)与算法的实现(含全部代码)

本人b站账号:lady_killer9

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/416820
推荐阅读
相关标签
  

闽ICP备14008679号