剑指offer+面试题6-链表-从尾到头打印链表(java解答)

题目描述

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

思路

1. 将链表中链接节点的指针反转,从头到尾输出。但该方法改变了原来链表的结构

2. 栈:从头到尾遍历,从尾到头输出

  • 时间复杂度:O(N) 每个节点均遍历,然后栈顶元素依次输出
  • 空间复杂度:O(N) 创建一个堆栈,将链表的所有节点,从头到尾入栈,再从尾到头出栈

3. 递归:本质是一个栈结构

  • 每访问一个节点,先递归输出其后面节点,再输出该节点自身,从而实现反转
  • 缺点:链表非常长时,函数调用层级很深,导致函数调用溢出
  • 时间复杂度:O(N)
  • 空间复杂度:O(1)

github链接:

T06_LinkedList

T06_PrintListInReversedOrder

//利用栈“后进先出”的特点实现从尾到头打印链表
	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();
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值