Node.java:
package com.me.node;
/**
* 组成链表的结点对象
* @author wuyizuokan
*
* @param <T>
*/
public class Node<T> {
/*节点中存放的值*/
private T value;
/*下一个节点的引用*/
private Node<T> next;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
}
NodeList.java:
package com.me.node;
/**
* 链表实现类
* @author wuyizuokan
*
* @param <T>
*/
public class NodeList<T> {
/*链表头节点*/
private Node<T> head;
/**
* 向链表添加元素
* @param t
*/
public void add(T t) {
Node<T> node = new Node<T>();
node.setValue(t);
if (head == null) {
head = node;
} else {
add(head, node);
}
}
private void add(Node<T> node, Node<T> newNode) {
if (node.getNext() == null) {
node.setNext(newNode);
} else {
add(node.getNext(), newNode);
}
}
/**
* 根据分组反转链表
* @param i
*/
public void reverseGroup(int groupSize) {
head = reverseGroup(head, groupSize);
}
private Node<T> reverseGroup(Node<T> node, int i) {
// splitNode用于取数组的前i个元素,下面的for循环会让splitNode移动到第i个节点的位置
Node<T> splitNode = node;
for (int j = 1; j < i; j++) {
if (splitNode != null) {
splitNode = splitNode.getNext();
} else {
break;
}
}
// 如果移动到第i个节点的位置后,节点为null,说明无法达到一组的大小,则反转后直接返回
if (splitNode == null) {
return reversList(node);
}
// 标记好剩下的链表头,用于下一批分组
Node<T> nextListHead = splitNode.getNext();
// 设置splitNode的下一个节点为null,是为了把第i个节点前的链表抽取出来。
splitNode.setNext(null);
// 调用反转链表的方法进行反转。
Node<T> newHead = reversList(node);
// 递归调用按组反转数组的方法
Node<T> nextListHeadTmp = reverseGroup(nextListHead, i);
// 把下一次返回的反转的子列表拼接到这一次后面。
node.setNext(nextListHeadTmp);
// 返回新列表的头节点。
return newHead;
}
/**
* 反转列表
*/
public void reversList() {
head = reversList(head);
}
private Node<T> reversList(Node<T> node) {
// 这里作为递归的出口,相当于是用递归把链表按节点拆分,直到拆分到最后一个节点
if (node == null || node.getNext() == null) {
return node;
}
// 递归调用反转列表的方法,返回新列表的头部
Node<T> result = reversList(node.getNext());
// 因为是递归,这里的node实际上是从倒数第二个节点开始往前的每一个节点。需要把它的下一个
// 节点的下一个节点指向它自己。
node.getNext().setNext(node);
// 把自己的下一个节点置空,实际上整个函数执行完了之后,除了之前的头节点的下一个节点引用会为空外,其他节点不会。
node.setNext(null);
return result;
}
public void showList() {
System.out.print("[");
if (head != null) {
showNode(head);
}
System.out.println("]");
}
public void showNode(Node<T> node) {
if (node != null) {
System.out.print(node.getValue());
if (node.getNext() != null) {
System.out.print(", ");
showNode(node.getNext());
}
}
}
}
测试代码:
package com.me.reverseLinkedList;
import com.me.node.NodeList;
public class Test {
public static void main(String[] args) {
NodeList<String> nodeList = new NodeList<String>();
nodeList.showList();
nodeList.add("a");
nodeList.add("b");
nodeList.add("c");
nodeList.add("d");
nodeList.add("e");
nodeList.add("f");
nodeList.add("g");
nodeList.add("h");
nodeList.showList();
// 反转链表
nodeList.reversList();
nodeList.showList();
// 分组反转链表
nodeList.reverseGroup(3);
nodeList.showList();
}
}
运行效果:
Q.E.D.