/**
* 问题:反转部分单向链表
* 给定一个单向链表的头节点head,以及两个整数from和to,在单向链表上把第form个节点到第to个节点这一部分进行反转。
* 例如:
* 1->2->3->4->5->null, from=2, to=4
* 调整结果为: 1->4->3->2->5->null
* 再如:
* 1->2->3->null, from=1, to=3
* 调整结果为: 3->2->1->null
*
* 要求:
* 1.如果链表长度为 N, 时间复杂度要求为O(N), 额外空间复杂度要求为0(1)。
* 2.如果不满足 1<=from<=to<=N, 则不用调整。
* 分析:
* 本题有可能存在换头的问题, 比如题目的第二个例子,所以函数应该返回调整后的新
* 头节点, 整个处理过程如下:
*
* 1. 先判断是否满足1<=from<=to<=N, 如果不满足,则直接返回原来的头节点。
*
* 2. 找到第 from-1个节点fPre和第 to+1个节点tPos。fPre即是要反转部分的前一个节
* 点, tPos是反转部分的后一个节点。把反转的部分先反转,然后正确地连接 fPre和 tPos。
* 例如: 1->2->3->4>-null, 假设 fPre为节点 1, tPos为节点 4,要反转部分为2->3。
* 先反转成3->2, 然后 fPre连向节点 3, 节点 2连向 tPos,就变成了1->3->2->4->null。
*
* 3. 如果 fPre为 null, 说明反转部分是包含头节点的, 则返回新的头节点,也就是没反转之前反
* 转部分的最后一个节点, 也是反转之后反转部分的第一个节点; 如果 fPre不为 null,则直接
* 返回原头节点即可。
*
*
* @author 雪瞳
*
*/
*代码
public class Node<T> {
public T value;
public Node next;
public Node(T data){
this.value=data;
}
}
public class ReversePartNode { //链表长度 private int nodeLength = 0; //反转前一节点 private Node prefixNode = null; //反转后一节点 private Node suffixNode = null; //反转开始节点 private Node startNode = null; //反转结束节点 //private Node overNode = null; //指针节点 private Node currentNode = null; private Node currentNextNode =null; public Node reversePart(Node head,int from,int to) { currentNode =head; while(currentNode!=null) { nodeLength++; //判断当前节点是否是前置节点或者是后置节点 prefixNode = (nodeLength==from-1)?currentNode:prefixNode; suffixNode = (nodeLength==to+1)?currentNode:suffixNode; currentNode = currentNode.next; } //判断是否符合反转要求 if(from<1 || to>nodeLength || to<from) { return head; } //开始反转 //是否需要调整头节点 startNode = (prefixNode==null)?head:prefixNode.next; currentNode = startNode.next; startNode.next = suffixNode; while(currentNode!=suffixNode) { currentNextNode = currentNode.next; currentNode.next = startNode; startNode = currentNode; currentNode=currentNextNode; } if(prefixNode!=null) { //连接节点 prefixNode.next = startNode; return head; }else { return startNode; } } }
import java.util.Random;
import java.util.Scanner;
public class TestReversePartNode {
public static void main(String[] args) {
ReversePartNode reverse = new ReversePartNode();
TestReversePartNode test = new TestReversePartNode();
//获取初始信息
Random rand = new Random();
Scanner sc = new Scanner(System.in);
System.out.println("请输入链表长度");
int K = sc.nextInt();
System.out.println("请输入开始节点位置");
int from = sc.nextInt();
System.out.println("请输入结束节点位置");
int to = sc.nextInt();
//随机生成链表
Node nodes[]=new Node[K];
for(int i=0;i<nodes.length;i++) {
nodes[i]=new Node(rand.nextInt(20)+1);
}
for(int i =0;i<nodes.length-1;i++) {
nodes[i].next=nodes[i+1];
}
Node head = nodes[0];
//test
test.showNode(head);
Node reverseNode = reverse.reversePart(head, from, to);
test.showNode(reverseNode);
}
public void showNode(Node head) {
System.out.println("链表内的元素如下所示...");
while(head != null) {
System.out.print(head.value+" ");
head = head.next;
}
System.out.println();
}
}
*运行结果