链表反转(Java)

思路:

设置两个引用,一个为新链表的头结点,一个为遍历原链表的当前节点,遍历一次后,即可反转链表。

代码实现:

package com.datastructure.link;

import java.util.Stack;

/*
 * 数据结构之单链表
 */
public class SingleLinkedList
{

    /*
     * 元素的基本定义
     */
    static class Node{
        /*
         * value
         */
        private int value;
        
        /*
         * 链表的下一个元素
         */
        private Node next;
        
        public Node (int value) {
            this.value = value;
        }
        
        @Override
        public String toString() {
            if (this.next == null) {
                return String.valueOf(this.value);
            }
            return this.value + "->" + this.next.toString();
        }
        
    }
    
    /*
     * 反转单链表
     * 
     * 思路:遍历链表,把元素压入栈中,利用栈后进先出特性,遍历栈中元素,重组链表实现翻转
     * 
     * 分析:此方式简单易行,但是需要额外空间,需要遍历两次(一次链表+一次栈遍历)
     */
    public static Node reverseLinkedListByStack(Node node) {
        // 1、判空
        if (node == null) {
            return null;
        }
        
        // 2、链表元素压入栈中
        Node curNode = node;
        Stack<Node> stack = new Stack<>();
        while (curNode != null) {
            stack.push(curNode);
            curNode = curNode.next;
        }
        
        // 3、重组新链表
        Node newNode = stack.pop();
        
        // 遍历方案1
        /*
        Node tmpNode = newNode;
        while (!stack.isEmpty()) {
            Node curPopNode = stack.pop();
            tmpNode.next = curPopNode;
            tmpNode = curPopNode;
        }
        tmpNode.next = null;
        */
        // 遍历方案2
        ///*
        while(!stack.isEmpty()) {
            Node curPopNode = stack.pop();
            curPopNode.next.next = curPopNode;
            curPopNode.next = null;
        }
        //*/
        
        return newNode;
    }
    
    /* 
     * 反转单链表优化方案,只需遍历一次,遍历时拆开链表,当前元素指向前一个元素
     */
    public static Node reverseLinkedList(Node node) {
        if (node == null) {
            return null;
        }
        Node newNode = null;
        Node tmpNode = node;
        while (tmpNode != null) {
            // 缓存下一个节点便于while循环
            Node nextNode = tmpNode.next;
            // 改变当前遍历节点的指向
            tmpNode.next = newNode;
            // 推进新链表的头结点
            newNode = tmpNode;
            // while条件前移
            tmpNode = nextNode;
        }
        return newNode;
    }
    
    public static void main(String args[]) {
        // 原链表
        System.out.println("Origin link: " + createTestLinkedList());
        
        // 反转链表
        System.out.println("link reverse: " + reverseLinkedList(createTestLinkedList()));
        
    }
    
    private static Node createTestLinkedList() {
        Node head = new Node(0);
        Node curNode = head;
        for (int i = 1; i < 10; i++) {
            curNode.next = new Node(i);
            curNode = curNode.next;
        }
        return head;
    }

}

猜你喜欢

转载自blog.csdn.net/zangdaiyang1991/article/details/88573910