当前位置:   article > 正文

用链表类实现通讯录管理系统_链表通讯录管理系统

链表通讯录管理系统

我是周日下午开始写的,本来觉得这个作业很简单,老师只是说用class类写一个通讯录管理系统,没指明具体用啥数据结构,俺又不会用对象数组(明明ppt上有,只是偷懒不想看),所以就打算用类实现链表来完成这个系统。

很快啊,用了不到一个小时就写了个大框架,然后发现,tnnd我这个链表只能存一个人(当场气晕),事实上都不能叫链表了。然后啊,就去寻求万能的网友们的帮助,于是就发现了这篇大神写的博客,这里给下地址(16条消息) c++数据结构与算法(10)——链表(使用class实现)_北顾+的博客-CSDN博客_链表类

侵删(蒟蒻瑟瑟发抖)

namo接下来就来看看俺的bug系统8

目录

一、Node类的创建

二、List类的创建(重要)

三、完整代码

四、总结


一、Node类的创建

  1. class List;
  2. class Node
  3. {
  4. int data;
  5. string name;
  6. string tel;
  7. string qq;
  8. string address;
  9. string email;
  10. Node* next;
  11. public:
  12. friend class List;
  13. Node(string,string,string,string,string);
  14. };

因为是用类写的嘛,所以数据的隐蔽性是需要的,因此属性之类的都设为private,同时还需要一个next指针(见链表定义),而且这里有一个小细节,我们所需要构建的List链表类是需要设为Node类的友元类,如此List类才可以访问Node类的私有数据

还要注意一点,Node类的构造函数最好是给数据赋一个初始值,防止它乱跳数据,如下

  1. Node::Node(string name,string tel,string qq,string email,string address)
  2. {
  3. this->name = name;
  4. this->tel = tel;
  5. this->qq = qq;
  6. this->email = email;
  7. this->address = address;
  8. next = nullptr;
  9. }

二、List类的创建(重要)

  1. class List
  2. {
  3. Node *head;
  4. public:
  5. List();
  6. void Insert(string,string,string,string,string);
  7. void Show();
  8. void DeleteByName(string);
  9. void DeleteByQQ(string);
  10. void DeleteByTel(string);
  11. void SearchByName(string);
  12. void SearchByQQ(string);
  13. void SearchByTel(string);
  14. void ModifyByName(string,string,string,string,string);
  15. void ModifyByQQ(string,string,string,string,string);
  16. void ModifyByTel(string,string,string,string,string);
  17. };

嗯...这个链表我写的不是很完全,我是采用的头插法进行创建,遍历以及删除的,所以这里需要一个head指针并把它私有化。

同样的,LIst的构造函数也需要赋一个初始值,只需要把head置空就可

  1. List::List()
  2. {
  3. head = nullptr;
  4. }

然后,就是一些链表的基本用法,就像插入啊,删除啊,遍历啊啥的,看看就可,很简单。

如,这是链表的插入(我这里有药老师要求有三个数据是唯一的,所以在插入的时候遍历了一遍判断是否有重复元素)

  1. void List::Insert(string name,string tel,string qq,string email,string address)
  2. {
  3. Node* previous = nullptr;
  4. Node* current;
  5. for(current = head; current && (current->name != name || current->tel != tel || current->qq != qq); previous = current,current = current->next);
  6. if (current == nullptr)
  7. {
  8. Node* newNode = new Node(name,tel,qq,email,address);
  9. newNode->next = head;
  10. head = newNode;
  11. }
  12. }

如果不要求去重的话,可以看下面这一段

  1. Node* newNode = new Node(要存的数据);
  2. newNode->next = head;
  3. head = newNode;

然后,嗯....删除,如下

  1. void List::DeleteByName(string name)
  2. {
  3. Node* previous = nullptr; //上一个结点
  4. Node* current; //当前结点
  5. for(current = head;
  6. current && current->name != name;
  7. previous = current, current = current->next);
  8. if(current) //如果存在
  9. {
  10. if(previous)
  11. previous->next = current->next; //直接把上一个结点的next指向下一个结点
  12. else
  13. head = head->next; //如果上一个结点时头结点
  14. delete current;
  15. }
  16. }

也是从头结点开始遍历,找到要删除的位置,直接把它的上一个结点指向下一个结点就可以了

就像这样

然后就是查找...

  1. void List::SearchByName(string name)
  2. {
  3. Node* previous = nullptr;
  4. Node* current;
  5. for(current = head;
  6. current && current->name != name;
  7. previous = current, current = current->next);
  8. if(current)
  9. {
  10. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  11. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
  12. }
  13. else
  14. {
  15. cout << "不存在该名人类" << endl;
  16. }
  17. }

 和删除类似,先遍历到该位置之后输出即可,其实这里我本想用类似于这种形式的

  1. Node* Find(T)
  2. { Node*p; //代表对应位置的结点指针
  3. return p;
  4. }

但很可惜,这是类,用这种方式的话由于数据都是私有的,所以时没办法访问到的(蒟蒻大哭)

最后就是输出整个链表,从头到尾遍历输出一遍就好

  1. void List::SearchByName(string name)
  2. {
  3. Node* previous = nullptr;
  4. Node* current;
  5. for(current = head;
  6. current && current->name != name;
  7. previous = current, current = current->next);
  8. if(current)
  9. {
  10. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  11. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
  12. }
  13. else
  14. {
  15. cout << "不存在该名人类" << endl;
  16. }
  17. }

三、完整代码

有些注释没删,将就着看吧(你就是个大懒虫

  1. #include <iostream>
  2. using namespace std;
  3. class List;
  4. class Node
  5. {
  6. int data;
  7. string name;
  8. string tel;
  9. string qq;
  10. string address;
  11. string email;
  12. Node* next;
  13. public:
  14. friend class List;
  15. Node(string,string,string,string,string);
  16. };
  17. Node::Node(string name,string tel,string qq,string email,string address)
  18. {
  19. this->name = name;
  20. this->tel = tel;
  21. this->qq = qq;
  22. this->email = email;
  23. this->address = address;
  24. next = nullptr;
  25. }
  26. class List
  27. {
  28. Node *head;
  29. public:
  30. List();
  31. void Insert(string,string,string,string,string);//插入数据
  32. void Show();//显示数据
  33. void DeleteByName(string);//删除数据
  34. void DeleteByQQ(string);//删除数据
  35. void DeleteByTel(string);//删除数据
  36. void SearchByName(string);
  37. void SearchByQQ(string);
  38. void SearchByTel(string);
  39. void ModifyByName(string,string,string,string,string);
  40. void ModifyByQQ(string,string,string,string,string);
  41. void ModifyByTel(string,string,string,string,string);
  42. };
  43. List::List()
  44. {
  45. head = nullptr;
  46. }
  47. void List::Insert(string name,string tel,string qq,string email,string address)
  48. {
  49. Node* previous = nullptr;
  50. Node* current;
  51. for(current = head; current && (current->name != name && current->tel != tel && current->qq != qq); previous = current,current = current->next);
  52. if (current == nullptr)
  53. {
  54. //新建一个待插入的节点
  55. Node* newNode = new Node(name,tel,qq,email,address);
  56. //让头节点变为新节点的下一个节点指
  57. newNode->next = head;
  58. //让新插入的节点变为头节点
  59. head = newNode;
  60. }
  61. }
  62. void List::DeleteByName(string name)
  63. {
  64. Node* previous = nullptr;//保存上一个节点
  65. Node* current;//保存当前节点
  66. //空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
  67. for(current = head;
  68. current && current->name != name;
  69. previous = current, current = current->next);
  70. if(current)
  71. {
  72. //如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
  73. if(previous)//不是头节点
  74. previous->next = current->next;
  75. else // 是头节点的话直接指向头节点的下一节点即可
  76. head = head->next;
  77. delete current;//释放内存
  78. }
  79. }
  80. void List::DeleteByQQ(string qq)
  81. {
  82. Node* previous = nullptr;//保存上一个节点
  83. Node* current;//保存当前节点
  84. //空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
  85. for(current = head;
  86. current && current->qq != qq;
  87. previous = current, current = current->next);
  88. if(current)
  89. {
  90. //如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
  91. if(previous)//不是头节点
  92. previous->next = current->next;
  93. else // 是头节点的话直接指向头节点的下一节点即可
  94. head = head->next;
  95. delete current;//释放内存
  96. }
  97. }
  98. void List::DeleteByTel(string tel)
  99. {
  100. Node* previous = nullptr;//保存上一个节点
  101. Node* current;//保存当前节点
  102. //空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
  103. for(current = head;
  104. current && current->tel != tel;
  105. previous = current, current = current->next);
  106. if(current)
  107. {
  108. //如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
  109. if(previous)//不是头节点
  110. previous->next = current->next;
  111. else // 是头节点的话直接指向头节点的下一节点即可
  112. head = head->next;
  113. delete current;//释放内存
  114. }
  115. }
  116. void List::SearchByName(string name)
  117. {
  118. Node* previous = nullptr;
  119. Node* current;
  120. for(current = head;
  121. current && current->name != name;
  122. previous = current, current = current->next);
  123. if(current)
  124. {
  125. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  126. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
  127. }
  128. else
  129. {
  130. cout << "不存在该名人类" << endl;
  131. }
  132. }
  133. void List::SearchByQQ(string qq)
  134. {
  135. Node* previous = nullptr;
  136. Node* current;
  137. for(current = head;
  138. current && current->qq != qq;
  139. previous = current, current = current->next);
  140. if(current)
  141. {
  142. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  143. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
  144. }
  145. else
  146. {
  147. cout << "不存在该名人类" << endl;
  148. }
  149. }
  150. void List::SearchByTel(string tel)
  151. {
  152. Node* previous = nullptr;
  153. Node* current;
  154. for(current = head;
  155. current && current->tel != tel;
  156. previous = current, current = current->next);
  157. if(current)
  158. {
  159. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  160. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
  161. }
  162. else
  163. {
  164. cout << "不存在该名人类" << endl;
  165. }
  166. }
  167. void List::ModifyByName(string name,string newtel,string newqq,string newemail,string newaddress)
  168. {
  169. Node* previous = nullptr;
  170. Node* current;
  171. for(current = head; current && current->name != name; previous = current,current = current->next);
  172. if (current)
  173. {
  174. current->tel = newtel,current->qq = newqq,current->email = newemail,current->address = newaddress;
  175. }
  176. else
  177. {
  178. cout << "不存在该名人类" << endl;
  179. }
  180. }
  181. void List::ModifyByQQ(string qq,string newname,string newtel,string newemail,string newaddress)
  182. {
  183. Node* previous = nullptr;
  184. Node* current;
  185. for(current = head; current && current->qq != qq; previous = current,current = current->next);
  186. if (current)
  187. {
  188. current->name = newname,current->tel = newtel,current->email = newemail,current->address = newaddress;
  189. }
  190. else
  191. {
  192. cout << "不存在该名人类" << endl;
  193. }
  194. }
  195. void List::ModifyByTel(string tel,string newname,string newqq,string newemail,string newaddress)
  196. {
  197. Node* previous = nullptr;
  198. Node* current;
  199. for(current = head; current && current->tel != tel; previous = current,current = current->next);
  200. if (current)
  201. {
  202. current->name = newname,current->qq = newqq,current->email = newemail,current->address = newaddress;
  203. }
  204. else
  205. {
  206. cout << "不存在该名人类" << endl;
  207. }
  208. }
  209. void List::Show()
  210. {
  211. cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
  212. for(Node* current = head; current; current = current->next)
  213. {
  214. cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->email <<"\t"<< current->address <<"\t"<< endl;
  215. }
  216. }
  217. void menu()
  218. {
  219. printf("----------------通讯录管理系统--------------------\n");
  220. printf("You can choose the following operations:\n");
  221. printf("0.Exit system\n");
  222. printf("1.Add\n");
  223. printf("2.Browse\n");
  224. printf("3.Delete\n");
  225. printf("4.Modify\n");
  226. printf("5.Query\n");
  227. }
  228. List l;
  229. void keyDown()
  230. {
  231. string name, tel, qq, email, address, op;
  232. Node* p = nullptr;
  233. string newname, newtel, newqq, newemail, newaddress;
  234. int choice = 0;
  235. cin >> choice;
  236. switch (choice)
  237. {
  238. case 0:
  239. cout << "退出成功,感谢您的使用!";
  240. system("pause");
  241. exit(0);
  242. break;
  243. case 1:
  244. cout << "---------【录入信息】---------\n";
  245. cout << "请输入姓名,电话号码,QQ,Email,籍贯" << endl;
  246. cin >> name >> tel >> qq >> email >> address;
  247. l.Insert(name, tel, qq, email, address);
  248. break;
  249. case 2:
  250. cout << "---------【浏览信息】---------\n";
  251. l.Show();
  252. break;
  253. case 3: //这里需要可以用三种操作进行删除
  254. cout << "---------【删除信息】---------\n";
  255. cout << "请选择要删除的方式(姓名,电话,qq)" << endl;
  256. cin >> op;
  257. if (op == "姓名")
  258. {
  259. cout << "请输入需要删除的人的姓名" << endl;
  260. cin >> name;
  261. l.DeleteByName(name);
  262. }
  263. else if (op == "电话")
  264. {
  265. cout << "请输入需要删除的人的电话" << endl;
  266. cin >> tel;
  267. l.DeleteByTel(tel);
  268. }
  269. else if (op == "qq")
  270. {
  271. cout << "请输入需要删除的人的qq" << endl;
  272. cin >> qq;
  273. l.DeleteByQQ(qq);
  274. }
  275. else
  276. {
  277. cout << "输入错误,返回上一层" << endl;
  278. }
  279. break;
  280. case 4: //这里同样也是三种操作
  281. cout << "---------【修改信息】---------\n";
  282. cout << "请选择要修改的方式(姓名,电话,qq)" << endl;
  283. cin >> op;
  284. if (op == "姓名")
  285. {
  286. cout << "请输入需要修改信息的人的姓名" <<endl;
  287. cin >> name;
  288. cout << "请输入修改后的人的QQ" << endl;
  289. cin >> newqq;
  290. cout << "请输入修改后的人的电话号码" << endl;
  291. cin >> newtel;
  292. cout << "请输入修改后的人的Email" << endl;
  293. cin >> newemail;
  294. cout << "请输入修改后的人的籍贯" << endl;
  295. cin >>newaddress;
  296. l.ModifyByName(name,newtel,newqq,newemail, newaddress);
  297. }
  298. else if (op == "电话")
  299. {
  300. cout << "请输入需要修改信息的人的电话号码" <<endl;
  301. cin >> tel;
  302. cout << "请输入修改后的人的姓名" << endl;
  303. cin >> newname;
  304. cout << "请输入修改后的人的QQ" << endl;
  305. cin >> newqq;
  306. cout << "请输入修改后的人的Email" << endl;
  307. cin >> newemail;
  308. cout << "请输入修改后的人的籍贯" << endl;
  309. cin >>newaddress;
  310. l.ModifyByTel(tel,newname,newqq,newemail, newaddress);
  311. }
  312. else if (op == "qq")
  313. {
  314. cout << "请输入需要修改信息的人的QQ" <<endl;
  315. cin >> qq;
  316. cout << "请输入修改后的人的姓名" << endl;
  317. cin >> newname;
  318. cout << "请输入修改后的人的电话" << endl;
  319. cin >> newtel;
  320. cout << "请输入修改后的人的Email" << endl;
  321. cin >> newemail;
  322. cout << "请输入修改后的人的籍贯" << endl;
  323. cin >>newaddress;
  324. l.ModifyByQQ(qq,newname,newtel,newemail, newaddress);
  325. }
  326. else
  327. {
  328. cout << "输入错误,返回上一层" << endl;
  329. }
  330. break;
  331. case 5:
  332. cout << "---------【查找信息】---------\n";
  333. cout << "请选择要查找的方式(姓名,电话,qq)" << endl;
  334. cin >> op;
  335. if (op == "姓名")
  336. {
  337. cout << "请输入需要查找的人的姓名" << endl;
  338. cin >> name;
  339. l.SearchByName(name);
  340. }
  341. else if (op == "电话")
  342. {
  343. cout << "请输入需要查找的人的电话" << endl;
  344. cin >> tel;
  345. l.SearchByTel(tel);
  346. }
  347. else if (op == "qq")
  348. {
  349. cout << "请输入需要查找的人的qq" << endl;
  350. cin >> qq;
  351. l.SearchByQQ(qq);
  352. }
  353. else
  354. {
  355. cout << "输入错误,返回上一层" << endl;
  356. }
  357. break;
  358. default:
  359. cout << "选择错误,请重新输入" << endl;
  360. system("pause");
  361. break;
  362. }
  363. }
  364. int main()
  365. {
  366. while(1)
  367. {
  368. menu();
  369. keyDown();
  370. system("pause");
  371. system("cls");
  372. }
  373. return 0;
  374. }

四、总结

怎么说呢,这个作业说难是真的不难,说简单也有点麻烦,起初全是因为我想用链表写系统(不要掩饰你只会用链表写系统的笨),然后就学习了下链表类的写法,感觉其实还是有很大的优化空间的,整个代码看下来也就三四个部分的复制粘贴而已,也没有多大难度,嗯....就这样吧

期待有dalao给蒟蒻指正

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

闽ICP备14008679号