当前位置:   article > 正文

链表手撕代码(链表的创建、头插法、尾插法、部分反转、全部反转、链表的排序、链表的销毁)_java链表尾插法 手撕代码

java链表尾插法 手撕代码

链表作为基础数据结构中的必考知识点,考察指针操作。为了方便后期更好地总结学习,现将链表问题简单总结如下:

链表的创建、头插法、尾插法、部分反转、全部反转、链表的排序、链表的销毁。直接上代码:

  1. #include <stdlib.h>
  2. #include<iostream>
  3. #include<ctime>
  4. #include<queue>
  5. #include<functional>
  6. using namespace std;
  7. /* Definition for singly - linked list.*/
  8. struct ListNode {
  9. int val;
  10. ListNode *next;
  11. ListNode(int x) : val(x), next(NULL) {}
  12. };
  13. ListNode* reverseList(ListNode* head) {
  14. ListNode *prev = NULL;
  15. while (head) {
  16. ListNode* tmp = head->next;
  17. head->next = prev;
  18. prev = head;
  19. head = tmp;
  20. }
  21. return prev;
  22. }
  23. ListNode* insertNode(ListNode* head, int data) {
  24. ListNode* tmp = head;
  25. if (NULL == tmp)
  26. head = new ListNode(data);
  27. while (tmp->next) {
  28. tmp = tmp->next;
  29. }
  30. tmp->next = new ListNode(data);
  31. return head;
  32. }
  33. void printListNode(ListNode* head) {
  34. ListNode* tmp = head;
  35. while (tmp) {
  36. cout << tmp->val << " ";
  37. tmp = tmp->next;
  38. }
  39. }
  40. void freeListNode(ListNode* head) {
  41. ListNode* tmp = head;
  42. while (tmp) {
  43. ListNode* t = tmp->next;
  44. delete tmp;
  45. tmp = t;
  46. }
  47. }
  48. ListNode* reverseFromToListNode(int m, int n, ListNode* head) {
  49. if (m == n)return head;
  50. ListNode*pre = new ListNode(-1);
  51. pre->next = head;
  52. ListNode*prehead = pre;
  53. for (int i = 0; i < m; i++)
  54. {
  55. prehead = prehead->next;
  56. }
  57. n -= m; // n >= 1
  58. ListNode* pstart = prehead->next;
  59. //链表反转涉及到四个节点
  60. for (int i = 1; i <= n; i++)
  61. {
  62. ListNode* p = pstart->next;
  63. pstart->next = p->next;
  64. p->next = prehead->next;
  65. prehead->next = p;
  66. }
  67. return pre->next;
  68. }
  69. ListNode* reverseAll(ListNode* head) {
  70. ListNode* pre = NULL;
  71. while (head) {
  72. ListNode* t = head->next;
  73. head->next = pre;
  74. pre = head;
  75. head = t;
  76. }
  77. return pre;
  78. }
  79. ListNode* sort(ListNode *head)
  80. {
  81. ListNode *prev = NULL;
  82. ListNode *cur = NULL;
  83. ListNode *pre_new = NULL;
  84. ListNode *tmp = NULL;
  85. bool b_head = false;
  86. if (!head) {
  87. cout << "链表为空!" << endl;
  88. return head;
  89. }
  90. cur = head;
  91. while (cur) {
  92. if (!b_head)
  93. {
  94. prev = cur;
  95. cur = cur->next;
  96. prev->next = NULL;
  97. b_head = true;
  98. }
  99. else {
  100. if (cur->val<prev->val) //数据小于首结点
  101. {
  102. pre_new = cur->next;
  103. cur->next = prev;
  104. prev = cur;
  105. cur = pre_new;
  106. }
  107. else { //加入到新链表
  108. pre_new = prev;
  109. while (pre_new->next) //遍历新的链表
  110. {
  111. if ((cur->val)>(pre_new->next->val))
  112. {
  113. tmp = cur->next;
  114. cur->next = pre_new->next;
  115. pre_new->next = cur;
  116. cur = tmp;
  117. }
  118. else {
  119. pre_new = pre_new->next;
  120. }
  121. }
  122. //如果是结尾结点
  123. if (!(pre_new->next)) {
  124. tmp = cur->next;
  125. cur->next = NULL;
  126. pre_new->next = cur;
  127. cur = tmp;
  128. }
  129. }
  130. }
  131. }
  132. return prev;
  133. }
  134. ListNode* sortList(ListNode* head) {
  135. if (!head || !head->next) return head;
  136. //优先队列的第一个元素的是最大值
  137. priority_queue<int, std::vector<int>, std::greater<int>> q;
  138. ListNode* cur = head;
  139. while (cur) {
  140. q.push(cur->val);
  141. cur = cur->next;
  142. }
  143. cur = head;
  144. while (!q.empty()) {
  145. cur->val = q.top();
  146. q.pop();
  147. cur = cur->next;
  148. }
  149. return head;
  150. }
  151. ListNode* Sort(ListNode* SL)/*递增排序函数:入口参数:链表的头指针,此为链表中的排序函数*/
  152. {
  153. ListNode* p;
  154. ListNode* q;
  155. int temp;
  156. // 通过交换数据的方式
  157. for (p = SL; p != NULL; p = p->next)
  158. {
  159. for (q = p->next; q != NULL; q = q->next)
  160. {
  161. if (p->val > q->val)
  162. {
  163. temp = q->val;
  164. q->val = p->val;
  165. p->val = temp;
  166. }
  167. }
  168. }
  169. return SL;
  170. }
  171. int main() {
  172. srand(time(NULL));
  173. ListNode* head = new ListNode(0);
  174. for (int i = 0; i < 10; ++i) {
  175. head = insertNode(head, rand() % 100 + 100); // 产生[0, 100)的随机数
  176. }
  177. printListNode(head);
  178. cout<< endl << "reverse the listnode between 2 and 4" << endl;
  179. head = reverseFromToListNode(2, 4, head);
  180. printListNode(head);
  181. cout << endl << "reverse all the ListNode" << endl;
  182. head = reverseAll(head);
  183. printListNode(head);
  184. cout << endl << "after ListNode* sort" << endl;
  185. //head = Sort(head);
  186. head = sortList(head);
  187. printListNode(head);
  188. freeListNode(head);
  189. return 0;
  190. }

另外附上:链表的区间反转的示意图帮助理解消化。

 

链表排序问题:

一种是交换节点的数据,方法实现起来简单,但是效率低下。

第二种方法采用stl标准容器,即优先队列。

 

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

闽ICP备14008679号