题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
**解析:很多人第一反应是从头到尾输出将会比较简单,于是自然想到把链表中连接结点的指针反转过来,改变链表的方向即可。但该方法会改变原来链表的结构,是否允许在打印链表的时候修改链表的结构,这点取决于面试官的需求。
**通常打印是一个只读操作,我们不希望打印时修改内容。
**细读题意,第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出,这就是典型的“后进先出”!我们用栈来实现这种结构。
**既然用栈来实现,而递归本质上就是一个栈的结构,自然也可以用递归来实现。基于递归的代码看起来很简洁,但当链表非常长的时候,就会导致函数调用的层数很深,从而有可能导致函数调用栈溢出。
**显示用栈基于循环实现的代码的鲁棒性要好一些。
import java.util.Stack;
public class SolveProblem5 {
//非递归的方式,鲁棒性好
public static void printListReverse(listNode headNode){
Stack<listNode> stack=new Stack<listNode>();
while(headNode!=null)
{
stack.push(headNode);
headNode=headNode.next;
}
while(!stack.isEmpty())
{
System.out.println(stack.pop().data);
}
}
//递归方式,递归在本质上就是一个栈结构
public static void printListReverse_recursively(listNode headNode){
if(headNode!=null)
{
if(headNode.next!=null)
{
printListReverse_recursively(headNode.next);
}
System.out.println(headNode.data);
}
}
public static void main(String[] args) {
listNode node1=new listNode();
listNode node2=new listNode();
listNode node3=new listNode();
node1.data=1;
node2.data=2;
node3.data=3;
node1.next=node2;
node2.next=node3;
SolveProblem5 sp5=new SolveProblem5();
sp5.printListReverse(node1);
sp5.printListReverse_recursively(node1);
}
}
class listNode{
int data;
listNode next;
}
ps:本文参考《剑指offer:名企面试官精讲典型编程题》(何海涛著,北京:电子工业出版社,2012)和CSDN资源(http://download.csdn.net/detail/linda_lindaaaa /9055079)以及其他互联网资源。