题目描述
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路
1. 将链表中链接节点的指针反转,从头到尾输出。但该方法改变了原来链表的结构
2. 栈:从头到尾遍历,从尾到头输出
- 时间复杂度:O(N) 每个节点均遍历,然后栈顶元素依次输出
- 空间复杂度:O(N) 创建一个堆栈,将链表的所有节点,从头到尾入栈,再从尾到头出栈
3. 递归:本质是一个栈结构
- 每访问一个节点,先递归输出其后面节点,再输出该节点自身,从而实现反转
- 缺点:链表非常长时,函数调用层级很深,导致函数调用溢出
- 时间复杂度:O(N)
- 空间复杂度:O(1)
github链接:
//利用栈“后进先出”的特点实现从尾到头打印链表
public static void PrintListRerversely_Tteratively(ListNode pHead) {
Stack<ListNode> nodes=new Stack<>();
ListNode pNode=pHead;
while(pNode!=null)
{
nodes.push(pNode);
pNode=pNode.pNext;
}
while(!nodes.empty())
{
pNode=nodes.pop();
System.out.print(pNode.nKey);
}
}
//递归实现从尾到头,本质是一个栈结构
public static void PrintReversely_Recursively(ListNode pHead) {
if(pHead!=null) {
if(pHead.pNext!=null)
PrintReversely_Recursively(pHead.pNext);
System.out.print(pHead.nKey);
}
}
测试
- (功能测试)输入链表有多个节点
- (功能测试)输入链表只有一个节点
- (特殊输入测试)输入链表头结点为空null
public static void PrintList(ListNode pHead) {
ListNode pNode=pHead;
while(pNode!=null)
{
System.out.print(pNode.nKey);
pNode=pNode.pNext;
}
System.out.println();
}
//测试源码
public static void Test(ListNode pHead) {
System.out.println("输入的链表:");
PrintList(pHead);
System.out.println("栈实现从尾到头:");
PrintListRerversely_Tteratively(pHead);
System.out.println();
System.out.println("递归实现从尾到头:");
PrintReversely_Recursively(pHead);
System.out.println();
}
//1->2->3->4->5
public static void Test1()
{
System.out.println("Test1 begins.");
T06_LinkedList linkList=new T06_LinkedList();
ListNode root=new ListNode(1);
linkList.AddToTail(root, 2);
linkList.AddToTail(root, 3);
linkList.AddToTail(root, 4);
Test(root);
}
//只有一个结点的链表:1
public static void Test2()
{
System.out.println("Test2 begins.");
T06_LinkedList linkList=new T06_LinkedList();
ListNode root=new ListNode(1);
Test(root);
}
//空链表:null
public static void Test3()
{
System.out.println("Test3 begins.");
Test(null);
}
public static void main(String[] args) {
Test1();
//Test2();
//Test3();
}