写了一个单链表的代码,而且支持反转链表,分组反转链表
我的个人博客:https://www.wuyizuokan.com
Node.java:
1 package com.me.node; 2 3 /** 4 * 组成链表的结点对象 5 * @author wuyizuokan 6 * 7 * @param <T> 8 */ 9 public class Node<T> { 10 /*节点中存放的值*/ 11 private T value; 12 /*下一个节点的引用*/ 13 private Node<T> next; 14 15 public T getValue() { 16 return value; 17 } 18 public void setValue(T value) { 19 this.value = value; 20 } 21 public Node<T> getNext() { 22 return next; 23 } 24 public void setNext(Node<T> next) { 25 this.next = next; 26 } 27 }
NodeList.java:
1 package com.me.node; 2 3 /** 4 * 链表实现类 5 * @author wuyizuokan 6 * 7 * @param <T> 8 */ 9 public class NodeList<T> { 10 11 /*链表头节点*/ 12 private Node<T> head; 13 14 /** 15 * 向链表添加元素 16 * @param t 17 */ 18 public void add(T t) { 19 Node<T> node = new Node<T>(); 20 node.setValue(t); 21 if (head == null) { 22 head = node; 23 } else { 24 add(head, node); 25 } 26 } 27 28 private void add(Node<T> node, Node<T> newNode) { 29 if (node.getNext() == null) { 30 node.setNext(newNode); 31 } else { 32 add(node.getNext(), newNode); 33 } 34 } 35 36 /** 37 * 根据分组反转链表 38 * @param i 39 */ 40 public void reverseGroup(int groupSize) { 41 head = reverseGroup(head, groupSize); 42 } 43 44 private Node<T> reverseGroup(Node<T> node, int i) { 45 // splitNode用于取数组的前i个元素,下面的for循环会让splitNode移动到第i个节点的位置 46 Node<T> splitNode = node; 47 for (int j = 1; j < i; j++) { 48 if (splitNode != null) { 49 splitNode = splitNode.getNext(); 50 } else { 51 break; 52 } 53 } 54 // 如果移动到第i个节点的位置后,节点为null,说明无法达到一组的大小,则反转后直接返回 55 if (splitNode == null) { 56 return reversList(node); 57 } 58 // 标记好剩下的链表头,用于下一批分组 59 Node<T> nextListHead = splitNode.getNext(); 60 // 设置splitNode的下一个节点为null,是为了把第i个节点前的链表抽取出来。 61 splitNode.setNext(null); 62 // 调用反转链表的方法进行反转。 63 Node<T> newHead = reversList(node); 64 // 递归调用按组反转数组的方法 65 Node<T> nextListHeadTmp = reverseGroup(nextListHead, i); 66 // 把下一次返回的反转的子列表拼接到这一次后面。 67 node.setNext(nextListHeadTmp); 68 // 返回新列表的头节点。 69 return newHead; 70 } 71 72 /** 73 * 反转列表 74 */ 75 public void reversList() { 76 head = reversList(head); 77 } 78 79 private Node<T> reversList(Node<T> node) { 80 // 这里作为递归的出口,相当于是用递归把链表按节点拆分,直到拆分到最后一个节点 81 if (node == null || node.getNext() == null) { 82 return node; 83 } 84 85 // 递归调用反转列表的方法,返回新列表的头部 86 Node<T> result = reversList(node.getNext()); 87 // 因为是递归,这里的node实际上是从倒数第二个节点开始往前的每一个节点。需要把它的下一个 88 // 节点的下一个节点指向它自己。 89 node.getNext().setNext(node); 90 // 把自己的下一个节点置空,实际上整个函数执行完了之后,除了之前的头节点的下一个节点引用会为空外,其他节点不会。 91 node.setNext(null); 92 return result; 93 } 94 95 public void showList() { 96 System.out.print("["); 97 if (head != null) { 98 showNode(head); 99 } 100 System.out.println("]"); 101 } 102 103 public void showNode(Node<T> node) { 104 if (node != null) { 105 System.out.print(node.getValue()); 106 if (node.getNext() != null) { 107 System.out.print(", "); 108 showNode(node.getNext()); 109 } 110 } 111 } 112 }
测试代码:
1 package com.me.reverseLinkedList; 2 3 import com.me.node.NodeList; 4 5 public class Test { 6 public static void main(String[] args) { 7 NodeList<String> nodeList = new NodeList<String>(); 8 nodeList.showList(); 9 nodeList.add("a"); 10 nodeList.add("b"); 11 nodeList.add("c"); 12 nodeList.add("d"); 13 nodeList.add("e"); 14 nodeList.add("f"); 15 nodeList.add("g"); 16 nodeList.add("h"); 17 18 nodeList.showList(); 19 // 反转链表 20 nodeList.reversList(); 21 nodeList.showList(); 22 // 分组反转链表 23 nodeList.reverseGroup(3); 24 nodeList.showList(); 25 } 26 }
运行效果:
时间总是悄悄流逝