本博客参考自剑指offer 面试题5、面试题16
单链表反转有很多种解决方式,这里介绍两种单链表反转方式,1、利用递归来实现单链表反转,2、利用中间变量实现单链表反转。解题思路参考剑指offer。
1、递归实现单链表反转
(图1)
首先做一个栈,遍历整个链表,把d1 d2 d3 d4 d5 d6分别存入栈中,由于栈有先入后出的特性,所以出的顺序是 d6 d5 d4 d3 d2 d1 d0,这样已经是逆转了,d6的next指向d5,d5的next指向d4......这样就可以完成整个单链表的反转。这是一种解决途径,但是编码会略繁琐。
递归本身就是利用堆栈来实现的,所以该解决办法更简单的是通过递归来实现。通过具体代码来分析
//打印函数
public static void reversePrintLinkTable(Node node){
if(node!=null){
if(node.next!=null){
reversePrintLinkTable(node.next);
}
System.out.print(node.obj);
if(node.next==null){
headNew=node;
headNewBuff=headNew;
}else{
headNewBuff.next=node;
headNewBuff=headNewBuff.next;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkTableReverse ltr=new LinkTableReverse();
ltr.creatLinkTable(10);
Node n=head;
while(n.next!=null){
n=n.next;
System.out.print((Integer)(n.obj));
}
//反转打印完成
reversePrintLinkTable(head);
headNewBuff.next=null;
Node n1=headNew;
while(n1.next!=null){
System.out.print((Integer)(n1.obj));
n1=n1.next;
}
}
该递归通过函数通过reversePrintLinkTable来实现,判断node.next是不是等于null,如果等于null,则打印数据,然后取出节点。就图一来讲其实现过程,首先判断head,head不是null,则递归,直到d6的next为null,此时把d6的节点打印出来,把该节点当头结点,把该节点赋值给head头结点。大概是这样的过程。
2、用中间变量来实现该过程
递归实现该过程需要用到堆栈,这对内存来说是有一定的开销的。所以可以通过中间变量来实现该过程。需要三个中间指针变量,preNode currNode nextNode。每次把currNode的next指向preNode,然后整个指针右移一个单元,直到完成整个遍历过程,时间复杂度O(n),空间复杂度O(1),比递归的空间复杂度好。具体代码如下:
public void reverseLinkTable(){
Node pReversedHead=null;
Node pNode=head;
Node pPrev=null;
while(pNode!=null){
Node pNext=pNode.next;
if(pNext==null){
pReversedHead=pNode;
}
pNode.next=pPrev;
pPrev=pNode;
pNode=pNext;
}
while(pReversedHead!=null){
System.out.print(pReversedHead.obj);
pReversedHead=pReversedHead.next;
}
}
该完整demo上传到github上,地址为 https://github.com/xxniuren/Java-Offer- 如有需要可下载。