当前位置:   article > 正文

(三)Java数据结构之单链表(增删改查,末尾/有序添加、打印倒数第几个、反转链表、合并有序链表)_javalist 倒数第一个

javalist 倒数第一个

先看代码:

  1. package top.baikunlong.top.baikunlong.linkedlist;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. /**
  5. * @author baikunlong
  6. * @date 2020/10/8 10:26
  7. */
  8. public class SingleLinkedList {
  9. /**
  10. * 头指针
  11. */
  12. private Node head = new Node(0, "头指针");
  13. /**
  14. * 在最后添加节点
  15. *
  16. * @param node
  17. */
  18. public void add(Node node) {
  19. //首先找到最后个节点
  20. Node temp = head;//头节点不能移动,需要临时变量
  21. while (true) {
  22. if (temp.next == null) {//如果是最后个则添加
  23. temp.next = node;
  24. break;
  25. } else {
  26. temp = temp.next;//否则移动到下一个节点
  27. }
  28. }
  29. }
  30. /**
  31. * 根据序号插入
  32. *
  33. * @param node
  34. */
  35. public void addByNo(Node node) {
  36. Node temp = this.head;
  37. while (true) {
  38. if (temp.next == null) {//如果到了链表尾部,直接添加
  39. temp.next = node;
  40. return;
  41. } else if (temp.next.no > node.no) {//如果当前节点的next.no大于node.no,则在当前节点后添加node
  42. node.next = temp.next;
  43. temp.next = node;
  44. return;
  45. } else if (temp.next.no == node.no) {
  46. //如果等于则提示已存在
  47. System.out.printf("已存在 no=%d 的节点\n", node.no);
  48. return;
  49. }
  50. //如果均不是则往下遍历
  51. temp = temp.next;
  52. }
  53. }
  54. /**
  55. * 根据no删除
  56. *
  57. * @param no
  58. */
  59. public void deleteByNo(int no) {
  60. Node temp = this.head;
  61. while (true) {
  62. if (temp.next == null) {
  63. System.out.printf("节点为 no=%d 不存在\n", no);
  64. return;
  65. }
  66. if (temp.next.no == no) {
  67. temp.next = temp.next.next;
  68. return;
  69. }
  70. temp = temp.next;
  71. }
  72. }
  73. /**
  74. * 根据no更新
  75. *
  76. * @param node
  77. */
  78. public void updateByNo(Node node) {
  79. Node temp = this.head.next;
  80. while (true) {
  81. if (temp == null) {
  82. System.out.printf("节点为 no=%d 不存在\n", node.no);
  83. return;
  84. } else if (temp.no == node.no) {
  85. temp.name = node.name;
  86. return;
  87. }
  88. temp = temp.next;
  89. }
  90. }
  91. /**
  92. * 根据no获取
  93. *
  94. * @param no
  95. * @return
  96. */
  97. public Node getNodeByNo(int no) {
  98. Node temp = this.head.next;
  99. while (true) {
  100. if (temp == null) {
  101. throw new RuntimeException("节点为 no=" + no + " 不存在");
  102. } else if (temp.no == no) {
  103. return temp;
  104. }
  105. temp = temp.next;
  106. }
  107. }
  108. /**
  109. * 打印链表
  110. */
  111. public void list() {
  112. if (head.next == null) System.out.println("链表为空");
  113. Node temp = head.next;
  114. while (true) {
  115. if (temp == null) {
  116. break;
  117. } else {
  118. System.out.println(temp.toString());
  119. temp = temp.next;
  120. }
  121. }
  122. }
  123. /**
  124. * 链表长度
  125. *
  126. * @return
  127. */
  128. public int length() {
  129. if (head.next == null) return 0;
  130. Node temp = this.head.next;
  131. int length = 0;
  132. while (temp != null) {
  133. length++;
  134. temp = temp.next;
  135. }
  136. return length;
  137. }
  138. /**
  139. * 获取倒数第index个node
  140. *
  141. * @param index 倒数下标
  142. * @return
  143. */
  144. public Node getNodeByLastIndex(int index) {
  145. int length = length();
  146. if (index > length || index < 1) {
  147. return null;
  148. }
  149. Node temp = this.head.next;
  150. for (int i = 0; i < length - index; i++) {
  151. temp = temp.next;
  152. }
  153. return temp;
  154. }
  155. /**
  156. * 反转链表
  157. */
  158. public void reverse() {
  159. //当前节点
  160. Node currentNode = this.head.next;
  161. //用于存储当前节点的下一个节点
  162. Node next;
  163. //创建个新头,相当于一条新链表
  164. Node reverseHead = new Node(0, "反转链表的头节点");
  165. while (currentNode != null) {
  166. next = currentNode.next;//存储当前节点的下一个节点,等会currentNode下一个节点会变化
  167. //这两句实现了把新节点插入到头节点的next域,也就是最后进来的,放在了最前面,也就实现了反转
  168. currentNode.next = reverseHead.next;//currentNode的下一节点指向反转链表的头节点的下一节点
  169. reverseHead.next = currentNode;//再反转链表的头节点的下一节点指向currentNode
  170. currentNode = next;//当前节点向后走
  171. }
  172. this.head.next = reverseHead.next;
  173. }
  174. /**
  175. * 添加有序链表,保证合并后还是有序
  176. */
  177. public void orderedAddAll(SingleLinkedList list) {
  178. Node tHead = this.head;
  179. Node oldNode = this.head.next;//被合并链表的第一个节点
  180. Node newNode = list.head.next;//合并链表的第一个节点
  181. while (oldNode != null || newNode != null) {
  182. //如果其中一个链表到尾了,直接把剩余的那个链表加进去
  183. if (oldNode == null) {
  184. tHead.next = newNode;
  185. newNode = newNode.next;
  186. } else if (newNode == null) {
  187. tHead.next = oldNode;
  188. oldNode = oldNode.next;
  189. } else if (oldNode.no <= newNode.no) {//如果小于等于则把被合并链表的节点添加进去
  190. tHead.next = oldNode;
  191. oldNode = oldNode.next;
  192. } else {
  193. tHead.next = newNode;
  194. newNode = newNode.next;
  195. }
  196. tHead=tHead.next;
  197. }
  198. }
  199. public static void main(String[] args) {
  200. SingleLinkedList list = new SingleLinkedList();
  201. // System.out.println("按末尾添加:");
  202. // Node node = new Node(1, "张三");
  203. // Node node2 = new Node(2, "李四");
  204. // Node node3 = new Node(3, "王五");
  205. // list.add(node);
  206. // list.add(node2);
  207. // list.add(node3);
  208. System.out.println("按no序号添加:");
  209. Node node = new Node(1, "张三");
  210. Node node3 = new Node(3, "王五");
  211. Node node2 = new Node(2, "李四");
  212. list.addByNo(node);
  213. list.addByNo(node3);
  214. list.addByNo(node2);
  215. list.list();
  216. list.deleteByNo(3);
  217. System.out.println("删除3后");
  218. list.list();
  219. System.out.println("删除33后");
  220. list.deleteByNo(33);
  221. list.list();
  222. System.out.println("更新2后");
  223. node2.name = "李小四";
  224. list.updateByNo(node2);
  225. list.list();
  226. System.out.println("获取no=1");
  227. System.out.println(list.getNodeByNo(1).toString());
  228. System.out.println("长度:" + list.length());
  229. System.out.println("倒数第一个:" + list.getNodeByLastIndex(1));
  230. System.out.println("倒数第二个:" + list.getNodeByLastIndex(2));
  231. System.out.println("倒数第三个:" + list.getNodeByLastIndex(3));
  232. System.out.println("添加几条数据:");
  233. list.add(new Node(10, "测试10"));
  234. list.add(new Node(20, "测试20"));
  235. list.add(new Node(30, "测试30"));
  236. list.list();
  237. System.out.println("反转链表:");
  238. list.reverse();
  239. list.list();
  240. //合并有序的
  241. SingleLinkedList list2 = new SingleLinkedList();
  242. list2.addByNo(new Node(1,"111"));
  243. list2.addByNo(new Node(3,"333"));
  244. list2.addByNo(new Node(7,"777"));
  245. list2.addByNo(new Node(9,"999"));
  246. list2.addByNo(new Node(5,"555"));
  247. SingleLinkedList list3 = new SingleLinkedList();
  248. list3.addByNo(new Node(2,"222"));
  249. list3.addByNo(new Node(4,"444"));
  250. list3.addByNo(new Node(0,"000"));
  251. list3.addByNo(new Node(6,"666"));
  252. list2.orderedAddAll(list3);
  253. System.out.println("合并有序链表list2和list3:");
  254. list2.list();
  255. }
  256. }
  257. /**
  258. * 节点类
  259. */
  260. class Node {
  261. public int no;
  262. public String name;
  263. public Node next;
  264. public Node(int no, String name) {
  265. this.no = no;
  266. this.name = name;
  267. }
  268. @Override
  269. public String toString() {
  270. return "Node{" +
  271. "no=" + no +
  272. ", name='" + name + '\'' +
  273. '}';
  274. }
  275. }

反转有一定难度,看着图比较好理解:

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

闽ICP备14008679号