2-22逆序打印链表

题目描述

  • 给定一个链表,从尾到头打印每一个元素。

解题方法1

  • 链表是链式存储结构,不同于数组,没有办法直接逆序遍历。
  • 第一反应,我们可以借助于栈或数组,先顺序遍历链表把所有元素存储到数组或栈中,然后再遍历数组或栈进行逆序打印。
  • 空间复杂度为n,时间复杂度为n,不推荐。

public class Test {
    public static void main(String[] args) throws Exception {
        int[] arr = {10,20,30,40,50};
        Node head = create(arr);
        show(head);
    }
    //逆序打印
    public static void show(Node head){
        if(head==null){
            return;
        }
        Stack s = new Stack();
        //入栈
        for(Node p =head.next;p!=null;p=p.next){
            s.push(p.val);
        }
        //出栈
        while(!s.empty()){
            System.out.print(s.pop() + " ");
        }
    }

    //创建单链表
    public static Node create(int[] arr){
        Node head = new Node(0); //头节点
        Node newnode = null; //指向新节点
        Node tail = head; //指向链表尾节点
        for(int a:arr){
            newnode = new Node(a);
            newnode.next = tail.next;
            tail.next = newnode;
            tail = newnode;
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}

解题方法2

  • 既然可以使用栈解决,那么很自然想到可以使用递归来解决,对于每一层递归只打印第一个节点元素。
public class Test {
    public static void main(String[] args) throws Exception {
        int[] arr = {10,20,30,40,50};
        Node head = create(arr);
        show(head.next);
    }
    //逆序打印
    public static void show(Node head){
        if(head==null){
            return;
        }
        show(head.next); //对于每一层递归都是先打印后续部分再打印第一个节点
        System.out.println(head.val);
    }

    //创建带头节点单链表
    public static Node create(int[] arr){
        Node head = new Node(0); //头节点
        Node newnode = null; //指向新节点
        Node tail = head; //指向链表尾节点
        for(int a:arr){
            newnode = new Node(a);
            newnode.next = tail.next;
            tail.next = newnode;
            tail = newnode;
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}

解题方法3

  • 我们也可以将链表反转再顺序打印,最后再将链表还原。
  • 此方法时间复杂度也为n,但是系数为3。
public class Test {
    public static void main(String[] args) throws Exception {
        int[] arr = {10,20,30,40,50};
        Node head = create(arr);
        show(head);
    }
    //逆序打印
    public static void show(Node head){
        reverse(head); //打印前反转
        for(Node p=head.next;p!=null;p=p.next){
            System.out.print(p.val+" ");
        }
        reverse(head);//打印后还原
    }

    //反转链表
    public static Node reverse(Node head){
        if(head==null || head.next==null){
            return head;
        }
        Node p = head.next;
        head.next = null;
        while(p!=null){
            Node temp = p.next;
            p.next = head.next;
            head.next = p;
            p=temp;
        }
        return head;
    }
    //创建单链表
    public static Node create(int[] arr){
        Node head = new Node(0); //头节点
        Node newnode = null; //指向新节点
        Node tail = head; //指向链表尾节点
        for(int a:arr){
            newnode = new Node(a);
            newnode.next = tail.next;
            tail.next = newnode;
            tail = newnode;
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值