[算法]反转单向链表和双向链表

题目:

分别实现反转单向链表和双向链表的函数。

要求:

如果链表长度为N,时间复杂度为O(N),额外空间复杂度要求为O(1)。

程序:

反转单向链表:

public class Node{
  public Node(int data){
    this.value=data;
  }
  public int value;
  public Node next;
}
public static Node reverseList(Node node){
  Node pre=null;
  Node next=null;
  while(head!=null){
    next=head.next;
    head.next=pre;
    pre=head;
    head=next;
  }
  return pre;
}

反转双向链表:

public class DoubleNode{
	public DoubleNode(int data){
		this.value=data;
	}
	public int value;
	public DoubleNode next;
	public DoubleNode pre;
}
public static DoubleNode reverseList(DoubleNode node){
	DoubleNode pre=null;
	DoubleNode next=null;
	while(head!=null){
		next=head.next;
		head.next=pre;
		head.pre=next;
		pre=head;
		head=next;
	}
	return pre;
}

题目二:

反转部分单向链表:

给定一个单向链表的头结点head,以及两个整数from和to,在单向链表上把第from个节点到第to个节点这一部分进行反转。

如果不满足1<=from<=to<=N,则不用调整。

核心思路:

找到from的前一个节点和to的后一个节点。

public class Node{
	public int value;
	public Node next;
	public Node(int value){
         this.value=value;
	}
}
public static Node reversePart(Node node,int from,int to){
	int len=0;
	Node node1=head;
	Node fPre=null;
	Ndoe tPos=null;
	while(node1!=null){
		len++;
		//找到from节点的前一个结点
		fPre=len==from-1?node1:fPre;
		//找到to节点的后一个节点
		tPos=len==to+1?node1:tPos;
	}
	//不满足条件时,直接返回head
	if (from>to||from<1||to>len) {
		return head;
	}
	//node1表示from的位置上的节点
	//判断反转的部分是否包含头结点,由于最后是返回head还是返回node1是不确定的,所以这一步的判断也是很必要的
	//如果反转的部分包含头结点,那么返回node1,因为head改变了,否则返回head
	node1=fPre==null?head:fPre.next;
	Node node2=node1.next;
	//将要反转的第一个节点与tPos连接起来
	node1.next=tPos;
	Node next=null;
	while(node2!=tPos){
		next=node2.next;
		node2.next=node1;
		node1=node2;
		node2=next;
	}
	if (fPre!=null) {
		//将要反转的最后一个节点与node1连接
		fPre.next=node1;
		return head;		
	}
	return node1;
}
posted @ 2016-03-07 17:52  小魔仙  阅读(1014)  评论(0编辑  收藏  举报