题目描述* 剑指offer面试题5:从尾到头打印链表
输入一个链表的头结点,从尾到头打印出每个结点的值
解决方案一:首先遍历链表的节点后打印,典型的“后进先出”,可以使用栈来实现这种顺序。
解决方案二:栈的本质就是递归,直接使用递归的方式,打印一个节点的时候先打印它后面的节点,再打印该节点自身,实现反向打印
解决方案三:遍历链表,把链表中的元素复制到ArrayList中,然后逆序打印ArrayList中的元素,由于ArrayList底层使用数组实现,所以用数组也是同样的原理
解决方案四:前三种解决方案本身属于在打印链表的时候不修改链表本身结构,在允许修改链表结构的情况下可以把链表中的节点指针反转过来,改变链表方向,然后重新遍历打印改变方向后的链表。
package com.offer.stack1;
/**
* @author kankan
* @creater 2019-05-10 22:50
*/
public class ListNode {
int value;//数据域
ListNode next = null;//指向下一节点的引用
public ListNode() {
}
public ListNode(int value) {
this.value = value;
}
}
package com.offer.stack1;
/**
* @author kankan
* @creater 2019-05-14 17:22
*/
public class LinkStack<T> {
//定义一个内部类节点,代表链栈的节点
private class LinkNode{
//保存节点数据
private T data;
//指向下一个节点的引用
private LinkNode next;
public LinkNode() {
}
public LinkNode(T data, LinkNode next) {
this.data = data;
this.next = next;
}
}
//保存该链栈的栈顶元素
private LinkNode top;
//保存该链栈中已包含的节点数
private int size;
//创建空链栈
public LinkStack() {
}
//返回链栈的长度
public int length(){
return size;
}
//进栈
public void push(T element){
//让top指向新创建的元素,新元素的next引用指向原来的栈顶元素
top = new LinkNode(element,top);
size++;
}
//出栈
public T pop(){
LinkNode oldTop = top;
//让top引用指向原栈顶元素的下一个元素
top = top.next;
//释放原栈顶元素的next引用
oldTop.next = null;
size--;
return oldTop.data;
}
//访问栈顶元素,但不删除栈顶元素
public T peek(){
return top.data;
}
//判断链栈是否为空栈
public boolean empty(){
return size == 0;
}
//清空链栈
public void clear(){
top = null;
size = 0;
}
}
package com.offer.stack1;
import java.util.ArrayList;
import java.util.Stack;
/**
* @author kankan
* @creater 2019-05-14 16:43
*/
public class Solution3 {
public static void main(String[] args) {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3=new ListNode(3);
ListNode node4=new ListNode(4);
node1.next=node2;
node2.next=node3;
node3.next=node4;
//方案一
System.out.println("=================方案一 自己写的栈==============");
printListFromTailToHeadByStack(node1);
System.out.println();
System.out.println("=================方案一==============");
printListFromTailToHeadByStack1(node1);
System.out.println();
System.out.println("=================方案二==============");
//方案二:递归法逆序打印链表
printListFromTailToHead(node1);
System.out.println();
System.out.println("=================方案三==============");
//方案三:使用ArrayList逆序打印链表
printListFromTailToHeadByArrayList(node1);
System.out.println();
System.out.println("=================方案四:递归反转链表后,遍历打印==============");
printListFromTailToHeadByReverseList(node1);
}
/*
* 方案一:通过使用栈结构,遍历链表,把先遍历的节点的值推入栈中,遍历结束后通过弹出栈内元素实现逆序打印
* 自己写的栈
*/
public static void printListFromTailToHeadByStack(ListNode node){
LinkStack<Integer> stack = new LinkStack<Integer>();
while (node != null){
stack.push(node.value);
node = node.next;
}
while (! stack.empty()){
System.out.print(stack.pop() + " ");
}
}
/*
* 方案一:通过使用栈结构,遍历链表,把先遍历的节点的值推入栈中,遍历结束后通过弹出栈内元素实现逆序打印
*/
public static void printListFromTailToHeadByStack1(ListNode node){
Stack<Integer> stack = new Stack<Integer>();
while (node != null){
stack.push(node.value);
node = node.next;
}
while (! stack.empty()){
System.out.print(stack.pop() + " ");
}
}
/*
* 方案二:递归法逆序打印链表
*/
public static void printListFromTailToHead(ListNode node){
if (node != null){
if (node.next != null){
//System.out.println("node.value: " + node.value);
printListFromTailToHead(node.next);
}
System.out.print(node.value + " ");
}else{
System.out.println("输入的链表为空");
}
}
/*
* 方案三:使用ArrayList逆序打印链表
*/
public static void printListFromTailToHeadByArrayList(ListNode node){
if (node == null){
System.out.println("输入链表为null");
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while (node != null){
arrayList.add(node.value);
node = node.next;
}
//ArrayList逆序打印链表
for (int i = arrayList.size() - 1; i >= 0;i--){
System.out.print(arrayList.get(i) + " ");
}
}
/*
* 方案四:递归反转链表后,遍历打印
*/
public static void printListFromTailToHeadByReverseList(ListNode head){
ListNode reverseNode = reverse(head);
while (reverseNode != null){
System.out.print(reverseNode.value + " ");
reverseNode = reverseNode.next;
}
}
//递归反转
private static ListNode reverse(ListNode head){
if (head.next == null){
return head;//3
}
ListNode reverse = reverse(head.next);
head.next.next = head;//反转链表 3.next.next = 3 ==> 4.next = 3; 2.next.next = 2 ==> 3.next = 2 1.next.next=1 ==> 2.next = 1
head.next = null;//3.next = null; 2.next = null 1.next = null
return reverse;
}
}