题目一:输入一个链表,反转链表后,输出新链表的表头。
方法一:取下头结点,然后将后面的节点使用头插法进行插入,直到最后一个节点为止,实现了链表的反转。
//第一种方法:将头结点取下,然后从第一个节点开始,依次插入到头结点的后面(头插法),直到最后一个节点为止
//在有头节点下
public ListNode ReverseList(ListNode head) {
if(head==null || head.next==null)
{
return head;
}
ListNode p;
ListNode r;
p=head.next;
head.next=null;
while(p!=null)
{
r=p.next;
p.next=head.next;
head.next=p;
p=r;
}
return head;
}
//没有头结点
public ListNode ReverseList1(ListNode head) {
if(head==null || head.next==null)
{
return head;
}
ListNode p;
ListNode r;
p=head.next;
head.next=null;
while(p!=null)
{
r=p.next;
p.next=head;
head=p;
p=r;
}
return head;
}
要注意这个链表有无头结点,有的话是把头结点取下,然后后面的节点在头结点之后采用头插法进行插入。
方法二:假设pre,p和r指向相邻的三个节点。经过若干操作,pre之间的节点已经都调整完毕,next指针都指向原来的前驱节点,现在让p的next指针指向pre。一旦进行调整,p后面的后继节点的链就断开了,为此需要r来指向原p指向后继节点。(这个就是迭代法)
//第二种方法:假设pre,p和r 指向三个相邻的节点,没有头节点
public ListNode ReverseList2(ListNode head){
if(head==null || head.next==null)
{
return head;
}
ListNode pre;
ListNode p;
ListNode r;
p=head;
r=p.next;
p.next=null;
while(r!=null)
{
pre=p;
p=r;
r=r.next;
p.next=pre;
}
return p;
}
//第二种方法:假设pre,p和r 指向三个相邻的节点,有头结点
public ListNode ReverseList3(ListNode head){
if(head==null || head.next==null)
{
return head;
}
ListNode pre;
ListNode p;
ListNode r;
p=head.next;
r=p.next;
p.next=null;
while(r!=null)
{
pre=p;
p=r;
r=r.next;
p.next=pre;
}
head.next=p;
return head;
}
要注意会出现下面的情况:
- 输入的链表的头指针是null
- 输入的链表只有一个节点
- 输入的链表有多个节点
迭代法简单:
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode next=null;
ListNode cur=head;
while(cur!=null)
{
next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
方法四:递归
//递归,假设从后面的节点已经反转,怎么连接,就是head.next(下一个节点).next(的下一个节点)=head(是现在的节点)
//然后递归有终止条件:就是head.next=null(也就是最后一个节点)
public ListNode reverseList(ListNode head) {
//终止条件
if(head==null || head.next==null)
{
return head;
}
ListNode node=reverseList(head.next);
head.next.next=head;
head.next=null;
return node;
}