单链表的反转与逆序打印

单链表的反转与逆序打印

破坏单链表结构

  1. 方式一:利用栈的特点,破坏原始链表结构,把各个节点的数据压入栈中,然后出栈,此时的栈底层还是数组这种数据结构
    //方法一:利用栈存储数据的特点完成倒叙输出
    public static void reverse1(Node head) {
        if (head != null) {
            //创建一个栈对象
            Stack<Node> stack = new Stack();//栈底层还是数组
            for (Node temp = head; temp != null; temp = temp.getNext()) {
                //把各个节点数据存入到栈对象中
                stack.push(temp);
            }
            //输出栈中各个元素
            while (stack.size() > 0){
                System.out.println(stack.pop().getData());
            }
        }
    }

栈底层结构

    /**
     * Adds the specified component to the end of this vector,
     * increasing its size by one. The capacity of this vector is
     * increased if its size becomes greater than its capacity.
     *
     * <p>This method is identical in functionality to the
     * {@link #add(Object) add(E)}
     * method (which is part of the {@link List} interface).
     *
     * @param   obj   the component to be added
     */
    public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }

  1. 方法二:根据方式一我们可以进一步联想,此时的栈是一个存储数据的容器,那么反过来这个容器也可以有我们自己创建,比如(数组,list,map)
    //根据方法一,那我们可以联想到只要把单向链表的各个节点数据遍历放到一个容器里面,倒叙输出就可以了
    //那个这个容器就可以是数组,list,map,栈底层实际是数组
    public static void reverse2(Node head) {
        if (head != null) {
            //创建一个list对象
            List<Node> list = new ArrayList<>();//ArrayList底层还是一个Object数组
            for (Node temp = head; temp != null; temp = temp.getNext()) {
                //把各个节点数据存入到list对象中
                list.add(temp);
            }
            //输出list中各个元素
            for (int i = list.size() - 1 ; i >= 0 ; i--) {
                System.out.println(list.get(i).getData());
            }
        }
    }

    //根据方法一,那我们可以联想到只要把单向链表的各个节点数据遍历放到一个容器里面,倒叙输出就可以了
    //那个这个容器就可以是数组,list,map,栈底层实际是数组
    public static void reverse3(Node head) {
        if (head != null) {
            //创建一个map对象
            Map<Integer,Node> map = new HashMap<>();
            int index = 0;
            for (Node temp = head; temp != null; temp = temp.getNext()) {
                //把各个节点数据存入到list对象中
                map.put(index,temp);
                index++;
            }
            //输出map中各个元素
            Set<Integer> set = map.keySet();
            for (int i = set.size() - 1; i >= 0 ;i--) {
                System.out.println(map.get(i).getData());
            }
        }
    }

不破坏单链表结构

  1. 方式一:使用普通遍历的方式
    //使用遍历的方式
    public static void reverse5(Node head) {
        Node pre = head;
        Node cur = head.getNext();
        Node temp;
        while (cur != null){
            temp = cur.getNext();
            cur.setNext(pre);
            pre = cur;
            cur = temp;
        }
        head.setNext(null);

        for (Node swap = pre; swap != null ; swap = swap.getNext()) {
            System.out.println(swap.getData());
        }
    }
  1. 方式二:使用双指针思想,先使用一个fast指针指向链表最后一个元素,然后在使用一个slow指针一次遍历链表,把指插入到fast.next(类似于头插法)直到slow和fast相同时停止遍历。
    //反转链表
    public static ListNode reverseList1(ListNode head) {
        if (head.next == null)return head;
        ListNode fast = head;
        while (fast.next != null){
            fast = fast.next;
        }
        ListNode slow = head;
        ListNode next = null,temp =null;
        while (slow != fast){
            next = slow.next;
            temp = slow;
            temp.next = fast.next;
            fast.next = temp;
            slow = next;
        }
        return fast;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值