题目:输入一个链表的头节点,从尾到头反过来打印每个节点的值。
三种实现方式:
- 改变原有链表,将链表指针反转,再进行遍历反转链表打印。
- 遍历链表,遍历过程中将元素放入到栈中,再依次出栈打印。
- 使用递归,反过来输出链表。
反转链表:
package com.example.offer;
import java.util.Stack;
/**
* 反向打印链表
*/
public class PrintListRever {
public static void main(String[] args) {
ListNode node01=new ListNode(1);
ListNode node02=new ListNode(2);
ListNode node03=new ListNode(3);
ListNode node04=new ListNode(4);
node01.next=node02;
node02.next=node03;
node03.next=node04;
//printList(reverList(node01));
//printListReverByStack(node01);
printListReverByRecurdion(node01);
}
/**
* 第一种方法:将链表反转
* @param head 链表的头节点
*/
public static ListNode reverList(ListNode head){
if(head==null || head.next==null){
return head;
}
ListNode tempNode;//记录剩余链表
ListNode node=head.next;//当前遍历节点
ListNode preNode=head;//保存前一节点
head.next=null;//将头元素的指针置空
while(node!=null){
tempNode=node.next;
node.next=preNode;
preNode=node;
node=tempNode;
}
return preNode;
}
/**
* 打印链表的值
* @param head
*/
public static void printList(ListNode head){
//定义临时节点
ListNode temp=head;
while(temp!=null){
System.out.println(temp.value);
temp=temp.next;
}
}
/**
* 第二种方法:利用栈结构反向打印链表
* 遍历链表,将节点的值压入栈中,再全部出栈打印
* @param head
*/
public static void printListReverByStack(ListNode head){
Stack stack=new Stack();
while(head!=null){
stack.push(head.value);
head=head.next;
}
while(!stack.isEmpty()){
System.out.println(stack.pop());
}
}
/**
* 方法三:采用递归,反向打印链表
* @param head
*/
public static void printListReverByRecurdion(ListNode head){
if(head!=null){
if(head.next!=null){
printListReverByRecurdion(head.next);
}
System.out.println(head.value);
}
}
}
/**
* 定义节点
*/
class ListNode{
int value;
ListNode next;
ListNode(int value){
this.value=value;
}
}
分析:第一种方法改变了原链表;递归在本质上就是一种栈结构,所以方法二与方法三原理相似,但是使用递归的方法,如果链表非常的长就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出,所以使用栈实现该题相对比较好。