链表题一般需要两个指针:
public class Node{
public int value;
public Node next;
public Node(int value){
this.value = data;
}
}
public class DoubleNode{
public int value;
public DoubleNode last ; // 指向上个节点
public DoubleNode next ; // 指向下一个节点
public DoubleNode(int data){
this.value = data;
}
}
public DoubleNode reverseList(DoubleNode head){
DoubleNode pre = null;
DoubleNode next = null;
while(head != null){
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}
public Node reverseList(Node head){
Node pre = null; // 记住前一个节点
Node next = null ;// 记住下一个节点
// 可以不用考虑空节点的问题
while(head != null){
next = head.next; // 由于要断开连接并反转指向,所以需要记住当前节点的下一个节点
head.next = pre; // 将当前节点指向下一个节点
pre = head; // 重置pre为head
head = next; // head像下移动
}
return pre; // 退出while循环时,head和next都为null,所以返回的是pre
}
// 本题有可能存在换头的问题,所以函数应该返回调整后的新头节点
public static Node reversePartNode(Node head, int from, int to){
int len = 0;
Node node1 = head;
Node fPre = null;
Node tPos = null;
// 找到要反转的前一个节点所以是from - 1,要找到调整的后一个节点所以是
// to + 1
while(node1 != null){
// 求出长度避免长度溢出
len ++;
// 这样可以少写一点
// 找到这个两个节点就不变了
fPre = len == from - 1 ? node1 : fPre;
tPos = len == to + 1 ? node1 : tPos;
node1 = node1.next;
}
// 排除的例外情况
if (from > to || from < 1 || to > len){
return head;
}
// 如果from是0,则是从第一个反转,相当于pre
node1 = fPre == null ? head : fPre.next;
// 为反转做准备
Node node2 = node1.next; // 相当于head,正在反转的位置
node1.next = tPos; // 先将反转后的最后一个与不需要反转的部分连接
Node next = null; // 记录反转的下一个节点
// 反转的主要代码
while(node2 != tPos){ // 退出条件是与后一个节点比较
next = node2.next;
node2.next = node1; // 将反转的与后面连接
node1 = node2;
node2 = next;
}
// 判断是不是交换了头
if (fPre != null){ // 没有换头
fPre.next = node1; // 连接反转之后的部分
return head;
}
return node1; // 已经换了头
}