当前位置:   article > 正文

北邮22信通:(6)实验1 题目三 :通讯录管理_数据结构实验利用线性表实现通讯录管理

数据结构实验利用线性表实现通讯录管理

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

获取更多文章  请访问专栏:

北邮22信通_青山如墨雨如画的博客-CSDN博客

目录

1. 实验要求:

2   程序分析:

2.1存储结构:

​编辑2.2关键算法分析:

        2.2.1.关键算法:

        2.2.2.代码详细分析:

3.完整代码

4.程序运行结果


1. 实验要求:

利用线性表实现一个通讯里管理系统,通讯录的数据格式如下:

Struct  datatype

{

       int ID;

char name[10];

char ch;

char phone[13];

char addr[31];

}

***编者注:为了实现更多功能,编者已将数据域扩展成了类***

要求:

实现通讯录的建立,增加,删除,修改,查询等功能;

能够实现简单的菜单交互,可以根据用户输入的命令选择不同的操作;

能够保存每次更新的数据;

编写main()函数测试线性表的正确性;

2   程序分析:

2.1存储结构

单链表:

2.2关键算法分析:

        2.2.1.关键算法:

                通讯录的增加数据、删除数据、修改数据、查询数据、打印数据、获得长度功能。

        2.2.2.代码详细分析:

                2.2.2.1单链表增加数据:

                        2.2.2.1.1头插法增加数据

                                时间复杂度:O(n)

                                获取插入位置的前一个结点的地址1;

                                新建一个节点,数据域赋值;

                                指针域指向地址1的下一个地址;

                                修改地址1的next指针,使之指向新增结点;

  1. template<class temp>
  2. inline void linklist<temp>::insert(int i, temp x)
  3. {
  4. node<temp>* p = this->front;
  5. if (i != 1)
  6. p = get(i - 1);
  7. if (p != NULL)
  8. {
  9. node<temp>* s = new node<temp>;
  10. s->data = x;
  11. s->next = p->next;
  12. p->next = s;
  13. }
  14. else
  15. {
  16. cout << "插入位置错误!" << endl;
  17. exit(0);
  18. }
  19. }

                        2.2.2.1.2自动将数据增添至链表末尾的方式增添数据

                                时间复杂度:O(n)

                                定义一个指针,遍历链表使指针指向最后一个结点;

                                新建一个结点,数据域赋值,指针域置空;

                                将指针指向的结点的next指针指向新建结点

  1. template<class temp>
  2. inline void linklist<temp>::addtorear(temp x)
  3. {
  4. node<temp>* p = this->front->next;
  5. while (p != NULL)
  6. p = p->next;
  7. node<temp>* s = new node<temp>;
  8. s->data = x;
  9. s->next = NULL;
  10. p->next = s;
  11. }

                2.2.2.2单链表删除数据

                        2.2.2.2.1按位置删除结点

                                时间复杂度:O(n)

                                获取删除位置的前一个结点的地址1(指针1);

                                定义指向要删除的结点的指针2;

                                将指针1所指向的结点的next指针指向指针2所指向的结点的next指针;

                                删除指针2所指向的结点地址;

  1. template<class temp>
  2. inline void linklist<temp>::del(int i)
  3. {
  4. node<temp>* p = this->front;
  5. if (i != 1)p = get(i - 1);
  6. node<temp>* q = p->next;
  7. p->next = q->next;
  8. temp x = q->data;
  9. delete q;
  10. cout << "删除的数据为:" << endl;
  11. x.print();
  12. }

                        2.2.2.2.2按值删除结点

                                时间复杂度:O(n)

                                定义指向有效起始位置(首结点)的指针;

                                遍历链表,寻找数据域相同的结点的前一个结点;

                                按照2.2.1方法删除链表结点;

  1. template<class temp>
  2. inline void linklist<temp>::del(temp x)
  3. {
  4. int flag = 0;
  5. node<temp>* p = this->front;
  6. while (p->next != NULL)
  7. {
  8. if (p->next->data == x)
  9. {
  10. node<temp>* q = p->next;
  11. p->next = q->next;
  12. delete q;
  13. cout << "删除数据完毕!" << endl;
  14. flag = 1;
  15. break;
  16. }
  17. p = p->next;
  18. }
  19. if (flag == 0)
  20. {
  21. cout << "未查询到数据!" << endl;
  22. }
  23. }

                2.2.2.3修改数据

                        时间复杂度:O(n)

                        获取修改数据的结点地址;

                        修改结点的数据域;

  1. template <class temp>
  2. inline void linklist<temp>::change(int i, temp x)
  3. {
  4. node<temp>* p = get(i);
  5. p->data = x;
  6. }

                2.2.2.4查询数据

                        2.2.2.4.1返回值类型为指针的get函数

                                时间复杂度:O(n)

                                定义指向首结点的指针;

                                遍历链表,直到符合 要求时停止;

                                返回指针;

  1. template<class temp>
  2. node<temp>* linklist<temp>::get(int i)
  3. {
  4. node<temp>* p = this->front->next;
  5. int j = 1;
  6. while (p != NULL && j != i)
  7. {
  8. p = p->next;
  9. j++;
  10. }
  11. return p;
  12. }

                        2.2.2.4.2返回值为该结点在单链表中的顺序的(int类型)的函数locate:

                                时间复杂度:O(n)

                                定义指向首结点的指针;

                                遍历链表,直到符合要求时停止;

                                返回计数变量的值;如果没有找到返回-1;

  1. template<class temp>
  2. inline int linklist<temp>::locate(temp x)
  3. {
  4. node<temp>* p = this->front->next;
  5. int j = 1;
  6. while (p != NULL)
  7. {
  8. if (p->data == x)return j;
  9. p = p->next;
  10. j++;
  11. }
  12. return -1;//如果没有找到,返回无效值
  13. }

3.完整代码

  1. #include<iostream>
  2. #include<iomanip>
  3. using namespace std;
  4. class phonebook
  5. {
  6. private:
  7. int ID;
  8. string name;
  9. string gender;
  10. string phone;
  11. string address;
  12. public:
  13. phonebook();
  14. phonebook(int, string, string, string, string);
  15. void getinfo(int, string, string, string, string);
  16. void print();
  17. void operator =(phonebook&);
  18. bool operator ==(phonebook&);
  19. };
  20. phonebook::phonebook()
  21. {
  22. this->ID = 0;
  23. this->name = "invalid_name";
  24. this->gender = "invalid_gender";
  25. this->phone = "unknown_phone_number";
  26. this->address = "unknown_address";
  27. }
  28. phonebook::phonebook(int ID, string name,
  29. string gender, string phone, string address)
  30. {
  31. this->ID = ID;
  32. this->name = name;
  33. this->gender = gender;
  34. this->phone = phone;
  35. this->address = address;
  36. }
  37. inline void phonebook::getinfo(int ID, string name,
  38. string gender, string phone, string address)
  39. {
  40. this->ID = ID;
  41. this->name = name;
  42. this->gender = gender;
  43. this->phone = phone;
  44. this->address = address;
  45. }
  46. inline void phonebook::print()
  47. {
  48. cout << setiosflags(ios::left);
  49. cout << "ID:" << setw(10) << this->ID;
  50. cout << "name:" << setw(10) << this->name;
  51. cout << "gender:" << setw(10) << this->gender;
  52. cout << "phone:" << setw(15) << this->phone;
  53. cout << "address:" << setw(10) << this->address;
  54. cout << endl;
  55. }
  56. inline void phonebook::operator=(phonebook& a)
  57. {
  58. this->ID = a.ID;
  59. this->name = a.name;
  60. this->gender = a.gender;
  61. this->phone = a.phone;
  62. this->address = a.address;
  63. }
  64. inline bool phonebook::operator==(phonebook& a)
  65. {
  66. int cnt = 0;
  67. if (this->ID == a.ID)cnt++;
  68. if (this->name == a.name)cnt++;
  69. if (this->gender == a.gender)cnt++;
  70. if (this->phone == a.phone)cnt++;
  71. if (this->address == a.address)cnt++;
  72. return (cnt == 5) ? true : false;
  73. }
  74. template<class temp>
  75. struct node
  76. {
  77. temp data;
  78. node<temp>* next;
  79. };
  80. template<class temp>
  81. class linklist
  82. {
  83. private:
  84. node<temp>* front;
  85. public:
  86. linklist()
  87. {
  88. this->front = new node<temp>;
  89. this->front->next = nullptr;
  90. }
  91. linklist(temp a[], int n);
  92. ~linklist();
  93. node<temp>* get(int i);
  94. void printlist();
  95. void printlength();
  96. int getlength();
  97. int locate(temp x);
  98. void insert(int i, temp x);
  99. void addtorear(temp x);
  100. void change(int i, temp x);
  101. void del(int i);
  102. void del(temp x);
  103. };
  104. template<class temp>
  105. linklist<temp>::linklist(temp a[], int n)
  106. {
  107. this->front = new node<temp>;
  108. this->front->next = NULL;
  109. for (int i = n - 1; i >= 0; i--)
  110. {
  111. node<temp>* s = new node<temp>;
  112. s->data = a[i];
  113. s->next = this->front->next;
  114. this->front->next = s;
  115. }
  116. }
  117. template<class temp>
  118. linklist<temp>::~linklist()
  119. {
  120. node<temp>* p = this->front;
  121. while (p != NULL)
  122. {
  123. this->front = p;
  124. p = p->next;
  125. delete this->front;
  126. }
  127. }
  128. template<class temp>
  129. node<temp>* linklist<temp>::get(int i)
  130. {
  131. node<temp>* p = this->front->next;
  132. int j = 1;
  133. while (p != NULL && j != i)
  134. {
  135. p = p->next;
  136. j++;
  137. }
  138. return p;
  139. }
  140. template <class temp>
  141. inline void linklist<temp>::printlist()
  142. {
  143. node<temp>* p = this->front->next;
  144. if (p == NULL)
  145. {
  146. cout << "p==NULL!" << endl;
  147. exit(0);
  148. }
  149. while (p != NULL)
  150. {
  151. p->data.print();
  152. p = p->next;
  153. }
  154. cout << endl;
  155. }
  156. template <class temp>
  157. inline void linklist<temp>::printlength()
  158. {
  159. node<temp>* p = this->front->next;
  160. int cnt = 0;
  161. while (p != NULL)
  162. {
  163. p = p->next;
  164. cnt++;
  165. }
  166. cout << endl << "有效学生信息为" << cnt << "个" << endl << endl;
  167. }
  168. template <class temp>
  169. inline int linklist<temp>::getlength()
  170. {
  171. node<temp>* p = this->front->next;
  172. int cnt = 0;
  173. while (p != NULL)
  174. {
  175. p = p->next;
  176. cnt++;
  177. }
  178. return cnt;
  179. }
  180. template<class temp>
  181. inline int linklist<temp>::locate(temp x)
  182. {
  183. node<temp>* p = this->front->next;
  184. int j = 1;
  185. while (p != NULL)
  186. {
  187. if (p->data == x)return j;
  188. p = p->next;
  189. j++;
  190. }
  191. return -1;//如果没有找到,返回无效值
  192. }
  193. template<class temp>
  194. inline void linklist<temp>::insert(int i, temp x)
  195. {
  196. node<temp>* p = this->front;
  197. if (i != 1)
  198. p = get(i - 1);
  199. if (p != NULL)
  200. {
  201. node<temp>* s = new node<temp>;
  202. s->data = x;
  203. s->next = p->next;
  204. p->next = s;
  205. }
  206. else
  207. {
  208. cout << "插入位置错误!" << endl;
  209. exit(0);
  210. }
  211. }
  212. template<class temp>
  213. inline void linklist<temp>::addtorear(temp x)
  214. {
  215. node<temp>* p = this->front->next;
  216. while (p != NULL)
  217. p = p->next;
  218. node<temp>* s = new node<temp>;
  219. s->data = x;
  220. s->next = NULL;
  221. p->next = s;
  222. }
  223. template <class temp>
  224. inline void linklist<temp>::change(int i, temp x)
  225. {
  226. node<temp>* p = get(i);
  227. p->data = x;
  228. }
  229. template<class temp>
  230. inline void linklist<temp>::del(int i)
  231. {
  232. node<temp>* p = this->front;
  233. if (i != 1)p = get(i - 1);
  234. node<temp>* q = p->next;
  235. p->next = q->next;
  236. temp x = q->data;
  237. delete q;
  238. cout << "删除的数据为:" << endl;
  239. x.print();
  240. }
  241. template<class temp>
  242. inline void linklist<temp>::del(temp x)
  243. {
  244. int flag = 0;
  245. node<temp>* p = this->front;
  246. while (p->next != NULL)
  247. {
  248. if (p->next->data == x)
  249. {
  250. node<temp>* q = p->next;
  251. p->next = q->next;
  252. delete q;
  253. cout << "删除数据完毕!" << endl;
  254. flag = 1;
  255. break;
  256. }
  257. p = p->next;
  258. }
  259. if (flag == 0)
  260. {
  261. cout << "未查询到数据!" << endl;
  262. }
  263. }
  264. int main()
  265. {
  266. system("color 0A");
  267. phonebook pbook[5] =
  268. {
  269. {1,"zhang","male","11111111111","a"},
  270. {2,"wang","female","22222222222","b"},
  271. {3,"li","male","33333333333","c"},
  272. {4,"zhao","female","44444444444","d"},
  273. {5,"liu","male","55555555555","e"}
  274. };
  275. linklist<phonebook>list(pbook, 5);
  276. while (1)
  277. {
  278. label0:
  279. cout << setw(41) << "欢迎来到通讯录管理系统!" << endl;
  280. cout << setw(40) << "*****增加数据请按1*****" << endl;
  281. cout << setw(40) << "*****删除数据请按2*****" << endl;
  282. cout << setw(40) << "*****修改数据请按3*****" << endl;
  283. cout << setw(40) << "*****查询数据请按4*****" << endl;
  284. cout << setw(40) << "*****显示数据请按5*****" << endl;
  285. cout << setw(40) << "*****退出查询请按6*****" << endl;
  286. cout << endl << "请输入序号:";
  287. int n0;
  288. cin >> n0;
  289. int flag = 1;
  290. switch (n0)
  291. {
  292. case 1:
  293. {
  294. cout << setw(40) << "欢迎来到数据增加界面!" << endl;
  295. cout << "请输入您想增加到通讯录中的先生/女士信息:" << endl;
  296. cout << "注意,请依次输入ID,姓名,性别," <<
  297. "电话号码和家庭住址,所有信息占一行" << endl;
  298. int ID; string name, gender, phone, address;
  299. cin >> ID >> name >> gender >> phone >> address;
  300. phonebook record0(ID, name, gender, phone, address);
  301. cout << "请输入您想将数据插入的位置序号:" << endl;
  302. int n1;
  303. cin >> n1;
  304. int length = list.getlength();
  305. if (n1 <= length)
  306. list.insert(n1, record0);
  307. else
  308. list.addtorear(record0);
  309. cout << "插入后的通讯录显示为:" << endl;
  310. list.printlist();
  311. break;
  312. }
  313. case 2:
  314. {
  315. cout << setw(40) << "欢迎来到数据删除界面!" << endl;
  316. label1:
  317. cout << "按顺序删除请按0,按值删除请按1" << endl;
  318. int n2;
  319. cin >> n2;
  320. switch (n2)
  321. {
  322. case 0:
  323. {
  324. int order;
  325. cout << "请输入删除的数据在通讯录中的顺序:";
  326. cin >> order;
  327. list.del(order);
  328. cout << "删除后的通讯录显示为:" << endl;
  329. list.printlist();
  330. break;
  331. }
  332. case 1:
  333. {
  334. cout << "请输入您想删除的先生/女士信息:" << endl;
  335. cout << "注意,请依次输入ID,姓名,性别," <<
  336. "电话号码和家庭住址,所有信息占一行" << endl;
  337. int ID; string name, gender, phone, address;
  338. cin >> ID >> name >> gender >> phone >> address;
  339. phonebook record1(ID, name, gender, phone, address);
  340. list.del(record1);
  341. cout << "删除后的通讯录显示为:" << endl;
  342. list.printlist();
  343. break;
  344. }
  345. default:
  346. {
  347. cout << "输入错误!" << endl;
  348. goto label1;
  349. break;
  350. }
  351. }
  352. break;
  353. }
  354. case 3:
  355. {
  356. cout << setw(40) << "欢迎来到数据修改界面!" << endl;
  357. cout << "请输入您想修改的先生/女士在通讯录中的顺序:";
  358. int n3;
  359. cin >> n3;
  360. cout << "请输入您想修改先生/女士信息:" << endl;
  361. cout << "注意,请依次输入ID,姓名,性别," <<
  362. "电话号码和家庭住址,所有信息占一行" << endl;
  363. int ID; string name, gender, phone, address;
  364. cin >> ID >> name >> gender >> phone >> address;
  365. phonebook record2(ID, name, gender, phone, address);
  366. list.change(n3, record2);
  367. cout << "修改后的通讯录为:" << endl;
  368. list.printlist();
  369. break;
  370. }
  371. case 4:
  372. {
  373. label2:
  374. cout << setw(40) << "欢迎来到数据查询界面!" << endl;
  375. cout << "请输入您想查询的先生/女士信息:" << endl;
  376. cout << "注意,请依次输入ID,姓名,性别," <<
  377. "电话号码和家庭住址,所有信息占一行" << endl;
  378. int ID; string name, gender, phone, address;
  379. cin >> ID >> name >> gender >> phone >> address;
  380. phonebook record3(ID, name, gender, phone, address);
  381. int pos = list.locate(record3);
  382. if (pos == -1)
  383. {
  384. cout << "该人员不在通讯录内,请问您是否继续查询?" << endl;
  385. cout << "如果选择继续查询请按1,不继续查询请按0" << endl;
  386. int n4;
  387. cin >> n4;
  388. switch (n4)
  389. {
  390. case 1:
  391. {
  392. goto label2;
  393. break;
  394. }
  395. case 0:
  396. break;
  397. default:
  398. break;
  399. }
  400. }
  401. else
  402. {
  403. cout << endl << "您查找的人员在通讯录中,"
  404. "在通讯录中的顺序为第" << pos << "个" << endl << endl;
  405. }
  406. break;
  407. }
  408. case 5:
  409. {
  410. cout << setw(40) << "欢迎来到数据显示界面!" << endl;
  411. list.printlength();
  412. cout << "您当前通讯录列表打印如下:" << endl;
  413. list.printlist();
  414. break;
  415. }
  416. case 6:
  417. {
  418. return 0;
  419. }
  420. default:
  421. {
  422. flag = 0;
  423. break;
  424. }
  425. }
  426. if (flag == 0)
  427. {
  428. cout << "上次输入无效,请重新输入!" << endl;
  429. goto label0;
  430. }
  431. }
  432. return 0;
  433. }
  434. /*
  435. 初始数据:
  436. 1 zhang male 11111111111 a
  437. 2 wang female 22222222222 b
  438. 3 li male 33333333333 c
  439. 4 zhao female 44444444444 d
  440. 5 liu male 55555555555 e
  441. 增加数据样例:
  442. 6 meng female 66666666666 f
  443. */

4.程序运行结果

代码效果图:

程序运行结果:

开始界面:用户输入功能选择的键值;

对每个界面均有输入错误处理机制,使用了label  goto语句;

部分功能为了更好满足用户需求,实现了switch语句的嵌套;

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

闽ICP备14008679号