题目:从尾到头打印链表
输入一个链表的头节点,从尾到头反过来打印输出每个节点的值。
算法分析:
看到这道题,很多人的第一反应是从头到尾输出将会比较简单,于是我们很自然的想到把链表中的节点的指针反转过来,改变链表的方向,然后就可以从头到尾输出了。但该方法改变原来链表的结构。是否允许在打印链表的时候修改链表的结构?这个取决于面试官的要求,因此在面试的时候我们要询问清楚面试官的要求。
通常打印是一个只读操作,我们不希望打印时修改内容。假设面试官也要求这个题目不能改变链表的结构。
接下来我们想到解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历的节点最后一个输出,而最后一个遍历到的节点第一个输出。这就是典型的'后进先出“,我们可以从栈实现这种顺序。没经过一个节点的时候,把该节点放到一个栈中。当遍历完整的链表后,再从栈顶开始逐个输出节点的值,此时输出的节点的顺序已经反转过来了。
既然想到了用栈来实现这个函数,而递归在本身上就是一个栈结构,于是自然就想到了用递归来实现。要实现反过来输出链表,我们没访问到一个节点的时候,先递归输出后面的 节点,再输出该节点本身,这样链表的输出结果就反过来了。
链表类:
class ListNode{
int val;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
算法源程序:
/**************************************************************
* Copyright (c) 2016, 北京邮电大学
* All rights reserved.
* 版 本 号:v1.0
* 题目描述:从尾到头打印链表
* 输入一个链表的头节点,从尾到头反过来打印输出每个节点的值。
* 输入描述:无
* 程序输出: 8 7 6 5 4 3 2 1
* 8 7 6 5 4 3 2 1
* 问题分析:无
* 算法描述:1.利用栈先入后出的特点,使用压栈的方式将链表放入栈中,再从栈顶依次取出值
* 2.采用递归的方法,每次访问到一个节点的时候,先递归输出它后面的节点,再输出该节点自身
* 完成时间:2016-10-27
***************************************************************/
package org.marsguo.offerproject05;
import java.util.Stack;
class ListNode{
int val;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
class SolutionMethod1{
/*
利用栈先入后出的特点,使用压栈的方式将链表放入栈中,再从栈顶依次取出值
*/
public void PrintListReversinglyIteratively(ListNode head){
if(head == null){
return ;
}
Stack<ListNode> stack = new Stack<>(); //使用栈
while(head != null){
stack.push(head);
head = head.next;
}
ListNode tmp;
while(!stack.isEmpty()){
tmp = stack.pop();
System.out.print(" " + tmp.val);
}
}
/*
采用递归的方法,每次访问到一个节点的时候,先递归输出它后面的节点,再输出该节点自身
*/
public void PrintListReversinglyRecursively(ListNode head){
if(head != null){
if(head.next != null){
PrintListReversinglyIteratively(head.next); //递归调用
}
System.out.print(" " + head.val);
}
}
}
public class PrintListReversingly {
public static void main(String[] args){
/*
* 输入链表:1->2->3->4->5->6->7->8->null
*/
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
ListNode n6 = new ListNode(6);
ListNode n7 = new ListNode(7);
ListNode n8 = new ListNode(8);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n7;
n7.next = n8;
n8.next = null;
SolutionMethod1 solution1 = new SolutionMethod1();
solution1.PrintListReversinglyIteratively(n1);
System.out.println();
solution1.PrintListReversinglyRecursively(n1);
}
}
程序运行结果: