面试题5-从头到尾打印链表
基础知识
链表是一种很常见的基本数据结构,因为它的结构简单,通过指针把若干个节点连接成链状结构。链表的创建、插入结点、删除结点等操作都是很容易实现的。链表是一种动态的数据结构,因为在创建链表的时候,无须知道链表的长度。当插入一个新的结点的时候,首先为新的节点分配内存,然后把指针指向新的节点。因为链表是通过指针链接的,不需要整块的连续内存,因此它的空间利用效率比数组高。但是这也造成了在链表中的查询只能从某一节点开始沿着指针遍历链表,它的时间效率为O(n)。下面实现一个简单的链表函数:
- class ListNode{
- public int val;
- public ListNode next = null;
- public ListNode(int val){
- this.val = val;
- }
- }
- void add(ListNode head, int val){
- ListNode n = new ListNode(val);
- if(head== null)
- head = n;
- else{
- ListNode tmp = head;
- while(tmp.next != null){
- tmp = tmp.next;
- }
- tmp.next = n;
- }
- }
-
- boolean remove(ListNode head, int val){
- if(head == null)
- return false;
- if(head.val == val){
- head = head.next;
- return true;
- }
- ListNode deletedNode = null;
- ListNode tmp = head;
- while(tmp.next != null && tmp.next.val != val){
- tmp = tmp.next;
- }
- if(tmp.next != null && tmp.next.val == val){
- deletedNode = tmp.next;
- tmp.next = tmp.next.next;
- return true;
- }
- return false;
- }
题目
输入一个链表的头结点,从头到尾反过来打印每个结点的值。
解题思路及代码
- 单向链表只能按照指针从头到尾一个方向来访问,这个要求的是从尾到头。可以借助栈来实现链表的反转。当从头到尾访问的时候,把链表的每一个结点压入到栈中,根据栈后进先出的特点,那么最后入栈的结点最先出栈,这样逐一输出栈中的结点,就能完成链表的反转。
- import java.util.ArrayList;
- import java.util.Stack;
- public class Solution {
- public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
- ArrayList<Integer> res = new ArrayList<>();
- if(listNode == null)
- return res;
- Stack<ListNode> s = new Stack<>();
- ListNode pos = listNode;
- while(pos != null){
- s.push(pos);
- pos = pos.next;
- }
- while(!s.isEmpty()){
- res.add(s.pop().val);
- }
- return res;
- }
- }
- 使用递归,当访问到每一个结点的时候,如果它的下一个结点不为空,那么先输出它后面的结点,然后输出它自身。(但是递归有个问题,当链表很长的时候,就会导致函数的调用的层级很深,这就有可能导致函数的调用栈溢出。
- import java.util.ArrayList;
- public class Solution{
- public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
- ArrayList<Integer> res = new ArrayList<>();
- if(listNode == null){
- return res;
- recursive(listNode,res);
- return res;
- }
- public void recursive(listNode node, ArrayList<Integer> res){
- if(node== null)
- return;
- else{
- recursive(node.next,res);
- }
- res.add(node.val);
- }
- }