当前位置:   article > 正文

C语言实现建立手机通讯录(顺序结构)_用数据结构编写通讯录

用数据结构编写通讯录

一.题目要求

今天来和大家分享一个简易通讯录(C语言实现)

首先要介绍一下通讯录的基本功能

  1. 添加联系人信息
  2. 删除指定联系人信息
  3. 查找指定联系人信息
  4. 修改指定联系人信息
  5. 显示所有联系人信息

二.思路分析

1. 首先需要定义通讯录的数据结构,可以使用结构体来表示每个联系人的信息,包括姓名、电话号码、地址等。

2. 接着需要定义一个数组来存储所有联系人的信息,数组的大小可以根据实际需求进行调整。

3. 编写程序菜单,包括添加联系人、删除联系人、查找联系人、显示所有联系人等功能。

4. 在添加联系人功能中,需要让用户输入联系人的信息,并将其存储到数组中。

5. 在删除联系人功能中,需要让用户输入要删除的联系人姓名,并在数组中查找并删除该联系人的信息。

6. 在查找联系人功能中,需要让用户输入要查找的联系人姓名,并在数组中查找并显示该联系人的信息。

7. 在显示所有联系人功能中,需要遍历数组并逐个显示每个联系人的信息。

8. 最后,可以使用文件读写功能将通讯录数据保存到文件中,以便下次启动程序时可以读取之前保存的数据。

总结,考虑到数据结构中的顺序表和单链表,我们可以采用这两种结构来实现。本文选择使用顺序表来实现,下一章可以通过单链表来实现。

三.各部分功能实现

1.定义通讯录结构

  •        在声明线性表的顺序存储类型时,定义一个data数组来存储线性表中的所有元素,定义一个整型变量length来存储线性表的实际长度,并采用结构体类型SqList表示。
  1. //定义通讯录结构表
  2. typedef struct {
  3. char name[20];
  4. char tel[15];
  5. } Elemtype;
  6. //声明顺序表
  7. typedef struct {
  8. Elemtype data[MaxSize]; //存放线性表中的元素是Elemtype所指代的通讯录结构体
  9. int length; //存放线性表的长度
  10. } SqList; //表示本次实验使用顺序表类型来完成通讯录的建立

2.初始化以及销毁线性表

  • 初始化线性表:该运算的功能是构造一个空的线性表L,实际上只需要分配线性表的存储空间并将 Length 域设置为0即可。
  • 销毁线性表:释放线性表L所占的内存空间。
  1. //初始化线性表
  2. void InitList(SqList *&L) {
  3. /*如果不方便理解,可以把L作为一个结构体指针,则下面操作可以理解为首先把分配的
  4. 一个结构体SqList一样大小的空间的首地址赋给L,L所指向的结构体中数据元素个数为0*/
  5. L = (SqList * )malloc(sizeof(SqList));
  6. L->length = 0;
  7. }
  8. //撤销(销毁)线性表
  9. void DestroyList(SqList *&L) {
  10. free(L); //释放指针L指向的顺序表空间
  11. }

3.插入数据元素

  •         该运算在顺序表L的第 i (1≤i≤n+1)个位置上插人新元素e。如果 i 值不正确,返回false;否则将顺序表原来的第i个元素及以后的元素均后移一个位置,并从最后一个元素an开始移动起。腾出一个空位置插入新元素,最后顺序表的长度增1并返回true。算法如下:
  1. //插入数据元素
  2. bool ListInsert(SqList *&L, int i, Elemtype e) {
  3. /*在顺序表L的第i个位置上插入新元素e*/
  4. int j;
  5. //参数i不正确时,返回false
  6. if (i < 1 || i > L->length + 1 || L->length == MaxSize)
  7. return false;
  8. i--; //将顺序表逻辑序号转化为物理序号
  9. //参数i正确时,将data[i]及后面的元素后移一个位置
  10. for (j = L->length; j > i; j--) {
  11. L->data[j] = L->data[j - 1];
  12. }
  13. L->data[i] = e; //插入元素e
  14. L->length++; //顺序表长度加1
  15. return true;
  16. }

4.删除数据元素

  •        该运算删除顺序表L的第 i (1≤i≤n)个元素。如果i值不正确,返回false;否则线性表第 i 个元素以后的元素均向前移动一个位置,并从元素a(i+1)开始移动起,这样覆盖了原来的第 i个元素,达到了删除该元素的目的,最后顺序表的长度减1并返回true。算法如下:
  1. //删除数据元素
  2. bool ListDelate (SqList *&L, int i, Elemtype &e) {
  3. /*删除顺序表中的第i个元素,其值为e*/
  4. int j;
  5. if (i < 1 || i > L->length)
  6. return false;
  7. i--; //将顺序表逻辑序号转化为物理序号
  8. e = L->data[i];
  9. //参数正确时,将data[i]之后的元素前移一个位置
  10. for (j = i; j < L->length - 1; j++)
  11. L->data[j] = L->data[j + 1];
  12. L->length--; //顺序表的长度减1
  13. return true;
  14. }

5.输出线性表

  • 依次显示L中各元素的值
  1. //输出线性表
  2. void DispList(SqList *L) {
  3. if (L->length == 0)
  4. printf("线性表为空");
  5. //扫描顺序表,输出各元素
  6. for (int i = 0; i < L->length; i++) {
  7. printf("%s %s", L->data[i].name, L->data[i].tel);
  8. printf("\n");
  9. }
  10. printf("\n");
  11. }

6.求某个数据元素值

  • 该运算用应用型参数e返回L中第i个元素的值
  1. //求某个数据元素值
  2. bool GetElem(SqList *L, int i, Elemtype &e) {
  3. if (i < 1 || i > L->length)
  4. return false; //参数i错误时,返回false
  5. e = L->data[i - 1]; //取元素值
  6. return true;
  7. }

7.元素查找

  • 该运算顺序查找第一个值域与e相等的元素的逻辑序号(找到后返回一个大于0的值),若这样的元素不存在,则返回值为0。
  1. //元素查找
  2. int LocateElem(SqList *L, Elemtype e) {
  3. /*顺序查找第一个值域与e相等的元素逻辑序号(根据e找i)*/
  4. int i = 0;
  5. //while循环查找e
  6. while (i < L->length && strcmp(L->data[i].name, e.name) != 0)
  7. i++;
  8. if (i >= L->length)
  9. return 0; //未找到返回0
  10. else
  11. printf("%s %s\n",L->data[i].name,L->data[i].tel);
  12. return i + 1; //找到后返回其逻辑序号
  13. }

四. 完整代码

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define MaxSize 50
  5. //定义通讯录结构表
  6. typedef struct {
  7. char name[20];
  8. char tel[15];
  9. } Elemtype;
  10. //声明顺序表
  11. typedef struct {
  12. Elemtype data[MaxSize]; //存放线性表中的元素是Elemtype所指代的通讯录结构体
  13. int length; //存放线性表的长度
  14. } SqList; //表示本次实验使用顺序表类型来完成通讯录的建立
  15. /*我们这里可以有两种思路来完成顺序表的建立,
  16. 第一(整体创建):由数组元素a[0···n-1]创建顺序表L,即将数组a中的每个元素依次放入顺序表中,并将n赋给顺序表的长度域。
  17. 前提是已经有一个数组存在,把它作为建立顺序表函数的参数进行传入。
  18. 第二(添加创建):先初始化一个空的顺序表,然后通过顺序表的添加元素函数进行补充,从而构建一个完整的顺序表。
  19. */
  20. //初始化线性表
  21. void InitList(SqList *&L) {
  22. /*如果不方便理解,可以把L作为一个结构体指针,则下面操作可以理解为首先把分配的
  23. 一个结构体SqList一样大小的空间的首地址赋给L,L所指向的结构体中数据元素个数为0*/
  24. L = (SqList * )malloc(sizeof(SqList));
  25. L->length = 0;
  26. }
  27. //撤销(销毁)线性表
  28. void DestroyList(SqList *&L) {
  29. free(L); //释放指针L指向的顺序表空间
  30. }
  31. //插入数据元素
  32. bool ListInsert(SqList *&L, int i, Elemtype e) {
  33. /*在顺序表L的第i个位置上插入新元素e*/
  34. int j;
  35. //参数i不正确时,返回false
  36. if (i < 1 || i > L->length + 1 || L->length == MaxSize)
  37. return false;
  38. i--; //将顺序表逻辑序号转化为物理序号
  39. //参数i正确时,将data[i]及后面的元素后移一个位置
  40. for (j = L->length; j > i; j--) {
  41. L->data[j] = L->data[j - 1];
  42. }
  43. L->data[i] = e; //插入元素e
  44. L->length++; //顺序表长度加1
  45. return true;
  46. }
  47. //删除数据元素
  48. bool ListDelate (SqList *&L, int i, Elemtype &e) {
  49. /*删除顺序表中的第i个元素,其值为e*/
  50. int j;
  51. if (i < 1 || i > L->length)
  52. return false;
  53. i--; //将顺序表逻辑序号转化为物理序号
  54. e = L->data[i];
  55. //参数正确时,将data[i]之后的元素前移一个位置
  56. for (j = i; j < L->length - 1; j++)
  57. L->data[j] = L->data[j + 1];
  58. L->length--; //顺序表的长度减1
  59. return true;
  60. }
  61. //输出线性表
  62. void DispList(SqList *L) {
  63. if (L->length == 0)
  64. printf("线性表为空");
  65. //扫描顺序表,输出各元素
  66. for (int i = 0; i < L->length; i++) {
  67. printf("%s %s", L->data[i].name, L->data[i].tel);
  68. printf("\n");
  69. }
  70. printf("\n");
  71. }
  72. //求某个数据元素值
  73. bool GetElem(SqList *L, int i, Elemtype &e) {
  74. if (i < 1 || i > L->length)
  75. return false; //参数i错误时,返回false
  76. e = L->data[i - 1]; //取元素值
  77. return true;
  78. }
  79. //元素查找
  80. int LocateElem(SqList *L, Elemtype e) {
  81. /*顺序查找第一个值域与e相等的元素逻辑序号(根据e找i)*/
  82. int i = 0;
  83. //while循环查找e
  84. while (i < L->length && strcmp(L->data[i].name, e.name) != 0)
  85. i++;
  86. if (i >= L->length)
  87. return 0; //未找到返回0
  88. else
  89. printf("%s %s\n",L->data[i].name,L->data[i].tel);
  90. return i + 1; //找到后返回其逻辑序号
  91. }
  92. //菜单实现
  93. void menu() {
  94. printf(" -------------------------------\n");
  95. printf(" 通讯录的应用:\n");
  96. printf(" -------------------------------\n");
  97. printf(" 1.建立(初始化)通讯录\n");
  98. printf(" 2.显示联系人信息\n");
  99. printf(" 3.增加联系人信息\n");
  100. printf(" 4.删除联系人信息\n");
  101. printf(" 5.查找联系人信息\n");
  102. printf(" 6.退出程序!!!\n");
  103. printf(" -------------------------------\n");
  104. }
  105. int main() {
  106. SqList *L;
  107. int flag = 1; //定义循环体条件
  108. int i, j; //存放用户输入的选项
  109. Elemtype a[4] = {"张三", "15671580583", "李四", "13387592396", "王五", "15994272725", "赵六", "15972200598"};
  110. Elemtype e;
  111. menu();
  112. printf("初始化顺序表并插入开始元素:\n");
  113. InitList(L); //这时是一个空表,接下来通过插入元素函数完成初始化
  114. for (int i = 0; i < 4; i++)
  115. ListInsert(L, i + 1, a[i]);
  116. DispList(L);
  117. while (flag == 1) {
  118. printf("请输入你的选择:\n");
  119. scanf("%d", &j);
  120. switch (j) {
  121. case 1:
  122. printf("已经完成初始化\n");
  123. break;
  124. case 2:
  125. DispList(L);
  126. break;
  127. case 3:
  128. printf("请输入联系人姓名与电话:");
  129. scanf("%s %s", e.name, e.tel);
  130. printf("请输入插入数据的位置:");
  131. scanf("%d", &i);
  132. printf("\n");
  133. ListInsert(L, i, e);
  134. break;
  135. case 4:
  136. printf("请输入删除数据的位置:");
  137. scanf("%d", &i);
  138. ListDelate(L, i, e);
  139. break;
  140. case 5:
  141. printf("请输入联系人姓名:");
  142. scanf("%s", &e.name);
  143. LocateElem(L, e);
  144. break;
  145. case 6:
  146. flag = 0;
  147. printf("退出程序\n");
  148. break;
  149. }
  150. }
  151. return 0;
  152. }

五.实验截图

补充:完整源代码在我上传的资源里有。 

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

闽ICP备14008679号