单链表反转迭代法和递归法的实现【详解】

前言

单链表反转是程序员必备的基本素养,经常在面试,笔试的过程中出现。理通实现思路,代码实现并不难。
首先我们来了解一下单链表结构。单链表是一种常见的数据结构,由多个结点连接而成,每个结点后面都会跟一个指针,指向下一个结点的内存地址。所以,每一部分就是有一个数据域和一个指针域构成。
LeetCode的反转链表原题描述:
题目描述:反转一个单链表

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

分析:
在遍历链表时,将当前结点的next指针改为指向前一个结点。由于结点没有引用其上一个结点,因此必须事先存储其前一个结点。在更改引用之前,还需要另一个指针来存储下一个结点,最后返回新的头引用。

编写思路:
所谓的单链表反转就是将链表的指针方向改变。但是,由于单链表没有指向前一个结点的指针,所以我们定义一个指向前一个结点的指针prev,用于存储每一个节点的前一个结点。接下来还需要定义一个保存当前结点的指针curr,以及下一个节点的nextTemp。定义好之后,遍历单链表,将当前结点的指针指向前一个结点,之后定义三个指针向后移动,直至遍历到最后一个结点为止。

迭代法

定义一个LinkedNode:

public class LinkedNode {

        Integer id;
        LinkedNode next;

        public LinkedNode(Integer id) {
            this.id = id;
        }

        // 打印链表
        public void print(){
            System.out.print(this.id);
            if (this.next != null) {
                System.out.print("->");
                this.next.print();
            } else {
                System.out.println();
            }
        }
}

迭代法实现方式:

public class NodeList {

        public static void main(String[] args) {
            LinkedNode node1 = new LinkedNode(1);
            LinkedNode node2 = new LinkedNode(2);
            LinkedNode node3 = new LinkedNode(3);
            LinkedNode node4 = new LinkedNode(4);
            LinkedNode node5 = new LinkedNode(5);

            node1.next = node2;
            node2.next = node3;
            node3.next = node4;
            node4.next = node5;

            // 打印链表
            System.out.println("链表:");
            node1.print();

            LinkedNode resNode = reverseList(node1);

            // 打印之后的链表
            System.out.println("反转之后的链表为:");
            resNode.print();
        }
    
    /***
     * 迭代反转
     * @param head
     * @return
     */
    public static LinkedNode reverseList(LinkedNode head) {
            LinkedNode prev = null;
            LinkedNode curr = head;
            while (curr != null) {
                LinkedNode nextTemp = curr.next;
                curr.next = prev;
                prev = curr;
                curr = nextTemp;
            }
            return prev;
        }
}

执行后的结果:
在这里插入图片描述

递归法

定义的LinkedNode同上面迭代法一样,这里就不赘述了。

public class NodeList {

        public static void main(String[] args) {
            LinkedNode node1 = new LinkedNode(1);
            LinkedNode node2 = new LinkedNode(2);
            LinkedNode node3 = new LinkedNode(3);
            LinkedNode node4 = new LinkedNode(4);
            LinkedNode node5 = new LinkedNode(5);

            node1.next = node2;
            node2.next = node3;
            node3.next = node4;
            node4.next = node5;

            // 打印链表
            System.out.println("链表:");
            node1.print();

            LinkedNode resNode = reverseList(node1);

            // 打印之后的链表
            System.out.println("反转之后的链表为:");
            resNode.print();
        }

        /**
         * 递归反转
         */
        public static LinkedNode reverseList(LinkedNode node) {

            // 如果为空链表或者只有一个节点的链表则不需要处理
            if (node == null || node.next == null) {
                return node;
            }
            // 递归直到找到尾结点
            LinkedNode newHead = reverseList(node.next);
            // 尾节点反指
            node.next.next = node;
            // 当前节点指向null节点
            node.next = null;
            return newHead;
        }
 }

运行结果:
在这里插入图片描述

发布了185 篇原创文章 · 获赞 201 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Sophia_0331/article/details/105241262