4.从尾到头打印链表
题目描述
从尾到头反过来打印出每个结点的值。
如:
input:
graph LR
1-->2
2-->3
output:
3,2,1
解题思路
1. 递归实现
要实现逆序打印链表 1->2->3;可以使用使用递归,先将链表看做当前节点和右侧节点两部分;如:1->(2->3),先打印右侧节点,再打印当前节点:右侧节点也可以看做两部分如:(2)->(3),也是先打印当前节点的右侧节点,在打印当前节点;如此递归,可实现逆序打印。
代码实现
java 代码
/**
* 单向链表节点
* @param <T>
*/
class LinkedNode<T extends Object>{
private T value;
private LinkedNode<T> next;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public LinkedNode<T> getNext() {
return next;
}
public void setNext(LinkedNode<T> next) {
this.next = next;
}
}
/**
* 反向打印链表
* @param node 链表首节点
* @return
*/
private ArrayList<Integer> printReverseLink( LinkedNode<Integer> node) {
ArrayList<Integer> list = new ArrayList();
if (node!=null){
list.addAll(printReverseLink(node.next));
list.add(node.value);
}
return list;
}
public static void main(String[] args){
LinkedNode<Integer> first = new LinkedNode<>();
first.setValue(1);
LinkedNode<Integer> two = new LinkedNode<>();
two.setValue(2);
LinkedNode<Integer> three = new LinkedNode<>();
three.setValue(3);
two.setNext(three);
first.setNext(two);
System.out.println(printReverseLink(first));
}
Kotlin 代码
/**
* 单向链表节点
*/
data class LinkedNode<T : Any?>(var value: T) {
var next: LinkedNode<T>? = null
}
/**
* 反向打印链表
* @param node 链表首节点
* @return
*/
private fun printReverseLink(node: LinkedNode<Int>?):ArrayList<Int> {
val list = ArrayList<Int>()
if (node!=null){
list.addAll(printReverseLink(node.next))
list.add(node.value)
}
return list
}
/**
* 入口函数
*/
fun main(args: Array<String>) {
val first = LinkedNode(1)
first.next = LinkedNode(2)
first.next?.next = LinkedNode(3)
print(printReverseLink(first))
}
2. 使用头插法
头插法顾名思义是将节点插入到头部:在遍历原始链表时,将当前节点插入新链表的头部,使其成为第一个节点。
链表的操作需要维护后继关系,例如在某个节点 node1 之后插入一个节点 node2,我们可以通过修改后继关系来实现:
node3 = node1.next;
node2.next = node3;
node1.next = node2;
为了能将一个节点插入头部,我们引入了一个叫头结点的辅助节点,该节点不存储值,只是为了方便进行插入操作。不要将头结点与第一个节点混起来,第一个节点是链表中第一个真正存储值的节点。
graph LR
1-->2
2-->3
引入head节点
graph LR
head
循环遍历链接,插入头结点后
node=1
graph LR
head-->1
node=2
graph LR
head-->2
2-->1
node=3
graph LR
head-->3
3-->2
2-->1
代码实现
java 代码
/**
* 头插法实现反向打印链表
*
* @param node 链表首节点
* @return
*/
private ArrayList<Integer> printReverseLinkToHead(LinkedNode<Integer> node) {
LinkedNode<Integer> head = new LinkedNode<>();
head.setValue(-1);
while (node != null) {
LinkedNode<Integer> next = node.getNext();
node.setNext(head.getNext());
head.setNext(node);
node = next;
}
ArrayList<Integer> list = new ArrayList();
head = head.getNext();
while (head != null) {
list.add(head.getValue());
head = head.getNext();
}
return list;
}
public static void main(String[] args){
LinkedNode<Integer> first = new LinkedNode<>();
first.setValue(1);
LinkedNode<Integer> two = new LinkedNode<>();
two.setValue(2);
LinkedNode<Integer> three = new LinkedNode<>();
three.setValue(3);
two.setNext(three);
first.setNext(two);
System.out.println(printReverseLinkToHead(first));
}
Kotlin 代码
/**
* 使用头插法反向打印链表
* @param node 链表首节点
* @return
*/
private fun printReverseLinkToHead(node: LinkedNode<Int>?):ArrayList<Int> {
var currentNode = node
var head:LinkedNode<Int>? = LinkedNode(-1)
while (currentNode!=null){
val next = currentNode.next
currentNode?.next = head!!.next
head!!.next = currentNode
currentNode = next
}
val list = ArrayList<Int>()
head = head!!.next
while (head!=null){
list.add(head.value)
head = head.next
}
return list
}
/**
* 入口函数
*/
fun main(args: Array<String>) {
val first = ListNode(1)
first.next = ListNode(2)
first.next?.next = ListNode(3)
print(printReverseLinkToHead(first))
}
3. 使用栈来实现
栈的规则时后进先出,则可以将链表遍历存放到栈中,然后在出栈则出栈顺序就是反向打印链表
代码实现
java 代码
/**
* 使用栈实现反向打印链表
*
* @param node 链表首节点
* @return
*/
private ArrayList<Integer> printReverseLinkToHeadWithStack(LinkedNode<Integer> node){
Stack<Integer> stack = new Stack<>();
while (node != null) {
stack.add(node.getValue());
node = node.next;
}
ArrayList<Integer> list = new ArrayList();
while (!stack.isEmpty()) {
list.add(stack.pop());
}
return list;
}
public static void main(String[] args){
LinkedNode<Integer> first = new LinkedNode<>();
first.setValue(1);
LinkedNode<Integer> two = new LinkedNode<>();
two.setValue(2);
LinkedNode<Integer> three = new LinkedNode<>();
three.setValue(3);
two.setNext(three);
first.setNext(two);
System.out.println(printReverseLinkToHeadWithStack(first));
}
Kotlin 代码
/**
* 使用栈反向打印链表
* @param node 链表首节点
* @return
*/
private fun printReverseLinkToHeadWithStack(node: LinkedNode<Int>?): ArrayList<Int> {
val stack = Stack<Int>()
var current = node
while (current != null) {
stack.push(current.value)
current = current.next
}
val list = ArrayList<Int>()
while (!stack.empty()) {
list.add(stack.pop())
}
return list
}
/**
* 入口函数
*/
fun main(args: Array<String>) {
val first = ListNode(1)
first.next = ListNode(2)
first.next?.next = ListNode(3)
print(printReverseLinkToHeadWithStack(first))
}
引用声明
该题目引用自
牛客网