顺序表

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<math.h>
  4. #include<time.h>
  5. #define OK 1
  6. #define ERROR 0
  7. #define TRUE 1
  8. #define FALSE 0
  9. #define MAXSIZE 20 //存储空间初始分配量
  10. typedef int Status; //函数的类型
  11. typedef int ElemType;//顺序表中元素的类型
  12. typedef struct { //顺序表结构体
  13. ElemType data[MAXSIZE];//存储数据元素的数组
  14. int length; //线性表当前长度
  15. } SqList;
  16. /*学习心得:
  17. *是直接访问运算符
  18. &是取地址运算符
  19. *&a与*(&a)等价,因为运算顺序一样,都是先取地址然后对地址进行访问。
  20. 所以*&a与*(&a)实际上都表示a
  21. 例如在当写函数体的时候,
  22. 函数头是这样的:
  23. Status InitList(SqList *L)
  24. 而在调用时,是这么使用的:
  25. SqList L;
  26. InitList(&L);
  27. 函数体中传入的东西实际上是L
  28. */
  29. //初始化线性表
  30. Status InitList(SqList *L) {
  31. L->length = 0; //使表长为0
  32. return OK;
  33. }
  34. /*
  35. ->远算符是什么意思?
  36. 成员选择(指针),选择结构体的成员变量
  37. 用法:对象指针->成员名
  38. 如:L->length
  39. */
  40. //增,插入元素
  41. Status ListInsert(SqList *L, int i, ElemType e) {
  42. int k;
  43. if (L->length == MAXSIZE) //错误发生在表的身上,如果表长已经达到最大值
  44. return ERROR;
  45. if (i < 1 || i > L->length + 1) //错误发生在插入位置的身上,如果插入位置<1或>表长+1
  46. return ERROR;
  47. if (i <= L->length) { //插入位置合理,如果插入位置i<=表长
  48. for (k = L->length; k >= i - 1; k--) //该for循环把i后面的元素都往后挪一位
  49. L->data[k + 1] = L->data[k];
  50. }
  51. L->data[i - 1] = e; //把元素e插入第i-1个位置
  52. L->length++; //表长+1
  53. return OK;
  54. }
  55. //删,删除第i个位置的元素e(和插入元素有微妙的区别)
  56. Status ListDelete(SqList *L, int i, ElemType *e) {
  57. int k;
  58. if (L->length == 0) //错误发生在表的身上,如果表长为0
  59. return ERROR;
  60. if (i < 1 || i > L->length) //错误发生在输入数的身上,如果插入位置<1或>表长(注意这边是L->length,而不是L->length+1)
  61. return ERROR;
  62. *e = L->data[i - 1]; //数组的下标从0开始,所以data数组的第i个元素的下标是i-1
  63. if (i < L->length) { //注意这边是<而不是<=
  64. for (k = L->length; k >= i - 1; k--)
  65. L->data[k - 1] = L->data[k];//往前挪
  66. }
  67. L->length--;
  68. return OK;
  69. }
  70. //查,返回线性表中第i个元素的值e
  71. Status GetElem(SqList L, int i, ElemType *e) {
  72. if (L.length == 0 || i < 1 || i > L.length)//如果线性表长为0或输入的数小于1或大于线性表表长
  73. return ERROR;
  74. *e = L.data[i];
  75. return OK;
  76. }
  77. //改,修改线性表的第i个元素为e
  78. Status UpdateElem(SqList *L, int i, ElemType newE) {
  79. if (L->length == 0 || i < 1 || i > L->length)//该条件与“查”函数的条件一致
  80. return ERROR;
  81. L->data[i] = newE;//为第i个元素赋new的值
  82. return OK;
  83. }
  84. //打印某个元素
  85. Status visit(ElemType c) {
  86. printf("%d", c);
  87. return OK;
  88. }
  89. //遍历顺序表
  90. //该方法不需要对顺序表进行修改,所以不采用指针型的形式参数。
  91. Status ListTraverse(SqList L) {
  92. int i;
  93. for (i = 0; i < L.length; i++)
  94. visit(L.data[i]);
  95. printf("\n");
  96. return OK;
  97. }
  98. //判断顺序表是否为空
  99. Status ListEmpty(SqList L) {
  100. if (L.length == 0)
  101. return TRUE;
  102. else
  103. return FALSE;
  104. }
  105. //将线性表置为空表
  106. Status ClearList(SqList *L) {
  107. L->length = 0;
  108. return OK;
  109. }
  110. //返回线性表中数据元素个数
  111. Status ListLength(SqList L) {
  112. return L.length;
  113. }
  114. //返回线性表中第一个与e满足相等关系的元素的位序
  115. Status LocateElem(SqList L, ElemType e) {
  116. int i;
  117. if (L.length == 0)
  118. return 0;
  119. for (i = 0; i < L.length; i++) { //从前往后找
  120. if (L.data[i] == e)
  121. break;
  122. }
  123. if (i >= L.length) //如果序号大于或等于表长
  124. return 0;
  125. return i + 1;
  126. }
  127. //合并顺序表
  128. void unionL(SqList *La, SqList Lb) {
  129. int La_len, Lb_len, i;
  130. ElemType e;
  131. La_len = ListLength(*La);
  132. Lb_len = ListLength(Lb);
  133. for (i = 1; i <= Lb_len; i++) {
  134. GetElem(Lb, i, &e);
  135. if (!LocateElem(*La, e))
  136. ListInsert(La, ++La_len, e);
  137. }
  138. }
  139. int main() {
  140. SqList L;
  141. ElemType e;
  142. Status i;
  143. int j, k;
  144. i = InitList(&L);
  145. printf("初始化后,L.length=%d\n", L.length);
  146. for (j = 1; j <= 5; j++)
  147. i = ListInsert(&L, 1, j);
  148. printf("在线性表表头插入1-5后,L.data=");
  149. ListTraverse(L);
  150. printf("目前,L.length=%d\n", L.length);
  151. i = ListEmpty(L);
  152. printf("L是否为空,i=%d(1:yes,0:no)\n", i);
  153. i = ClearList(&L);
  154. printf("清空后,L.length=%d\n", L.length);
  155. i = ListEmpty(L);
  156. printf("L是否为空,i=%d(1:yes,0:no)\n", i);
  157. for (j = 1; j <= 10; j++)
  158. i = ListInsert(&L, 1, j);
  159. printf("在线性表表头插入1-10后,L.data=");
  160. ListTraverse(L);
  161. printf("目前,L.length=%d\n", L.length);
  162. ListInsert(&L, 1, 0);
  163. printf("在表头插入0后,L.data=");
  164. ListTraverse(L);
  165. printf("L.length=%d\n", L.length);
  166. GetElem(L, 5, &e);
  167. printf("第五个元素为%d\n", e);
  168. for (j = 3; j <= 4; j++) {//找到值为3-4的元素
  169. k = LocateElem(L, j);
  170. if (k)
  171. printf("第%d个元素的值为%d\n", k, j);
  172. else
  173. printf("没有值为%d的元素", j);
  174. }
  175. k = ListLength(L);
  176. for (j = k + 1; j >= k; j--) {//尝试删除第k+1号元素以及第k号元素
  177. i = ListDelete(&L, j, &e);
  178. if (i == ERROR)
  179. printf("删除第%d个数据失败\n", j);
  180. else
  181. printf("删除的第%d个元素为%d\n", j, e);
  182. }
  183. printf("依次输出L的元素");
  184. ListTraverse(L);
  185. //构造一个有10个数的Lb
  186. SqList Lb;
  187. i = InitList(&Lb);
  188. for (j = 6; j < 15; j++)
  189. i = ListInsert(&Lb, 1, j);
  190. printf("依次输出Lb的元素");
  191. ListTraverse(Lb);
  192. unionL(&L, Lb);
  193. printf("依次合并后的顺序表");
  194. ListTraverse(L);
  195. printf("修改第四个元素为1000\n");
  196. UpdateElem(&L, 3, 1000);
  197. printf("顺序表变成");
  198. ListTraverse(L);
  199. system("pause");
  200. return 0;
  201. }





posted @ 2015-07-07 11:40  Lucas_1993  阅读(327)  评论(0编辑  收藏  举报