题目
从中间结点开始反转链表
例如
1->2->3->4->5 反转 1->2->5->4->3
1->2->3->4 反转后 1->2->4->3
思路
先找到中间结点,保存中间结点
从中间结点反转。
最后,将保存的中间结点和反转后的链接
其中,反转链表,用到了三个指针来控制的方法和头插法。
代码
package midReverseLinkedList;
//一个链表,反转从中间结点到最后一个结点的结点
public class Main {
public static class listNode {
int val;
listNode next;
listNode(int val, listNode node) {
this.val = val;
this.next = node;
}
}
// 利用三个指针来控制反转
public listNode reverseList(listNode head) {
if (head == null)
return null;
int N = 0;// list的长度
int midIndex = 0;
listNode pHead = head;
listNode midHead = head;
listNode left, mid, right = null;
while (pHead != null) {
++N;
pHead = pHead.next;
}
if (N == 1)
return head;
midIndex = N / 2;// 应该找指向中间结点的前一个结点
for (int i = 0; i < midIndex - 1; i++) {
midHead = midHead.next;
}
left = midHead.next;
mid = left.next;
if (left.next.next != null)
right = left.next.next;
left.next = null;// 先断开left-》right,再反转
while (right != null) {
mid.next = left;
left = mid;
mid = right;
right = right.next;
}
mid.next = left;
midHead.next = mid;
return head;
}
// 利用头插法来控制反转
public listNode reverseHeadList(listNode head) {
if (head == null)
return null;
int N = 0;// list的长度
int midIndex = 0;
listNode pHead = head;
listNode midHead = head;
listNode temp, pre = null, root = null;// root指向原链表的结点,pre保存最新的头结点,temp是动态结点。
while (pHead != null) {
++N;
pHead = pHead.next;
}
midIndex = N / 2;// 应该找指向中间结点的前一个结点
if (N == 1)
return head;
for (int i = 0; i < midIndex - 1; i++) {
midHead = midHead.next;
}
root = midHead.next;
while (root != null) {
temp = root;
root = root.next;
temp.next = pre;
pre = temp;
}
midHead.next = pre;
return head;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
listNode tail = new listNode(1, null);
listNode n2 = new listNode(2, tail);
listNode n3 = new listNode(3, n2);
listNode n4 = new listNode(4, n3);
listNode head = new listNode(5, n4);
Main m = new Main();
listNode p = m.reverseList(head);
while (p != null) {
System.out.print(p.val);
p = p.next;
}
}
}