剑指offer之C++语言实现链表(两种删除节点方式)

举报
chenyu 发表于 2021/07/27 00:49:13 2021/07/27
【摘要】 1 问题 用C++语言实现链表           2 代码实现 #include <iostream>#include <stdlib.h> using namespace std; class List{public: List(); ~List(); List*...

1 问题

用C++语言实现链表

 

 

 

 

 

2 代码实现


  
  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. class List
  5. {
  6. public:
  7. List();
  8. ~List();
  9. List* createNode(int value);//创建节点
  10. bool insertNode(List *node);//插入节点
  11. void printList();//打印节点
  12. bool deleteNode(List *node);//删除节点不移动头节点
  13. bool deleteNode1(List *node);//删除节点移动头节点
  14. int listSize();//长度
  15. void printNode();//打印但前的value
  16. void freeList();//释放链表
  17. private:
  18. int value;
  19. List *head;
  20. List *next;
  21. };
  22. bool List::deleteNode(List *node)
  23. {
  24. if (node == NULL)
  25. {
  26. std:cout << "node is NULL" << std::endl;
  27. return false;
  28. }
  29. if (head == NULL)
  30. {
  31. std::cout << "head is NULL" << std::endl;
  32. return false;
  33. }
  34. //如果node等于head
  35. if (head == node)
  36. {
  37. head = head->next;
  38. }
  39. List *p = head;
  40. while (p->next != NULL)
  41. {
  42. if (p->next == node)
  43. {
  44. p->next = p->next->next;
  45. return true;
  46. }
  47. p = p->next;
  48. }
  49. return false;
  50. }
  51. bool List::deleteNode1(List *node)
  52. {
  53. if (node == NULL)
  54. {
  55. std:cout << "node is NULL" << std::endl;
  56. return false;
  57. }
  58. if (head == NULL)
  59. {
  60. std::cout << "head is NULL" << std::endl;
  61. return false;
  62. }
  63. //如果node等于head
  64. if (head == node)
  65. {
  66. head = head->next;
  67. }
  68. List *p = head;
  69. while (head->next != NULL)
  70. {
  71. if (head->next == node)
  72. {
  73. head->next = head->next->next;
  74. std::cout << "delete node success head->value" << head->value << std::endl;
  75. //这里要记得把头节点的指针移动最后还原,这里的头节点是保存在这个类里面,改变了就是改变了
  76. //如果这里是把head作为参数传递,最后head会被销毁那么不需要移动头指针
  77. head = p;
  78. return true;
  79. }
  80. //注意,这里由于head是成员变量,改变了就是改变了,所以需要最后重新指定
  81. head = head->next;
  82. }
  83. std::cout << "delete node fail head->value" << head->value << std::endl;
  84. //这里要记得把头节点的指针移动最后还原,这里的头节点是保存在这个类里面,改变了就是改变了
  85. //如果这里是把head作为参数传递,最后head会被销毁那么不需要移动头指针
  86. head = p;
  87. return false;
  88. }
  89. List::List()
  90. {
  91. value = 0;
  92. head = NULL;
  93. next = NULL;
  94. }
  95. List::~List()
  96. {
  97. delete head;
  98. delete next;
  99. }
  100. List* List::createNode(int value)
  101. {
  102. List *list = NULL;
  103. list = new List();
  104. if (list)
  105. {
  106. list->value = value;
  107. return list;
  108. }
  109. return NULL;
  110. }
  111. bool List::insertNode(List *node)
  112. {
  113. node->next = head;
  114. head = node;
  115. return true;
  116. }
  117. void List::printList()
  118. { if (head == NULL)
  119. {
  120. std::cout << "head is NULL" << std::endl;
  121. return;
  122. }
  123. List *p = head;
  124. while (p != NULL)
  125. {
  126. std::cout << p->value << std::endl;
  127. p = p->next;
  128. }
  129. return;
  130. }
  131. void List::printNode()
  132. {
  133. std::cout << value << std::endl;
  134. }
  135. int List::listSize()
  136. {
  137. if (head == NULL)
  138. {
  139. std::cout << "head is NULL" << std::endl;
  140. return 0;
  141. }
  142. int len = 0;
  143. List *p = head;
  144. while (p != NULL)
  145. {
  146. p = p->next;
  147. ++len;
  148. }
  149. return len;
  150. }
  151. void List::freeList()
  152. {
  153. if (head == NULL)
  154. {
  155. std::cout << "head is NULL" << std::endl;
  156. return;
  157. }
  158. List *p;
  159. while (head != NULL)
  160. {
  161. p = head;
  162. head = head->next;
  163. free(p);
  164. }
  165. }
  166. int main()
  167. {
  168. List list;
  169. List *list1 = list.createNode(5);
  170. list.insertNode(list1);
  171. List *list2 = list.createNode(6);
  172. list.insertNode(list2);
  173. List *list3 = list.createNode(1);
  174. list.insertNode(list3);
  175. List *list4 = list.createNode(3);
  176. list.insertNode(list4);
  177. List *list5 = list.createNode(2);
  178. list.insertNode(list5);
  179. list.printList();
  180. std::cout << "list size is " << list.listSize() << std::endl;
  181. std::cout << "-----------开始删除节点值为3的节点" << std::endl;
  182. list.deleteNode1(list4);
  183. list.printList();
  184. std::cout << "list size is " << list.listSize() << std::endl;
  185. list.freeList();
  186. list.printList();
  187. return 0;
  188. }

 

 

 

 

 

 

3 运行结果


  
  1. 2
  2. 3
  3. 1
  4. 6
  5. 5
  6. list size is 5
  7. -----------开始删除节点值为3的节点
  8. delete node success head->value2
  9. 2
  10. 1
  11. 6
  12. 5
  13. list size is 4
  14. head is NULL

 

 

 

 

 

 

4 总结

很明显用C语言实现,我们习惯在外面搞个头结点,然后用C++实现,我们直接在类的里面放一个head指针,然后我们在增加节点的时候我们会把head进行移动,放在最前面,所以后面的 便利和删除操作等最好是不要动head的位置了,因为head动了,下次便利就有问题,如果删除函数移动了head,我们最后需要复原head

比如我们的头指针尽量不要移动,我们可以用一个指针变量来保存这个head指针,然后我们移动保存的指针变量,同时把保存的指针变量在一些情况下改变下一个指向的指针,那么我们下次便利head也是生效的,这样保证了头指针不被污染

比如下面的例子

 


  
  1. #include <stdio.h>
  2. void change(char *a)
  3. {
  4. *(a + 1) = 's';
  5. }
  6. int main()
  7. {
  8. char value[10] = "chenyu";
  9. change(value);
  10. printf("value is %s\n", value);
  11. return 0;
  12. }
  13. #include <stdio.h>
  14. void change(char *a)
  15. {
  16. char *p = a;
  17. *(p + 1) = 's';
  18. }
  19. int main()
  20. {
  21. char value[10] = "chenyu";
  22. change(value);
  23. printf("value is %s\n", value);
  24. return 0;
  25. }

其实最后的结果都是一样,csenyu

头指针是指向这块内存的地址,如果我们用指针变量保存了,然后这个指针变量也指向了这里,用指针变量去操作后,然后头指针也是指向这里,后面数据的指向也会改变

文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/86516967

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。