009 对于链表中next的作用以及翻转链表

声明

这篇文章是看了“左程云”老师在b站上的讲解之后写的, 自己感觉已经能理解这个题目了, 所以就将整个过程写下来, 下面的两段代码是直接可以运行的.

这个是“左程云”老师个人空间的b站的链接, 数据结构与算法讲的很好很好, 希望大家可以多多支持左程云老师, 真心推荐.
https://space.bilibili.com/8888480?spm_id_from=333.999.0.0

顺便提供一下测试链接:
https://leetcode.cn/problems/reverse-linked-list/

1. 解释“指向”问题

pre.next = cur1;

上面的代码是修改指向的问题,
其中, 左边的是需要重新指向(被修改)的, 右边的是被指向的.

翻译一下就是:将 pre 下一个指向的节点修改为 cur1.

2. 详细解释 next 的作用

pre.next = cur1;

这段代码的意义是:将 pre 指向的下一个节点更换为 cur1;
在这里插入图片描述

  • pre.next 在左边时,表示 pre 本身需要指向的下一个节点。
    在这里插入图片描述

  • pre.next 在右边时,表示 pre 当前指向的下一个节点。
    在这里插入图片描述

所以这个是一个问题, 要区分清楚, next被修改还是被指向.

3. 对代码的解释

3.1 思路

  1. 先设置一个头结点, 用来接受传过来的“链表”.
  2. 然后设置两个“指针”, pre(previous:上一个), next(下一个), 并且都设置为 null.
  3. 然后进入循环, 终止条件是:“head == null
  4. 然后将 next 指向下一个节点.
  5. 然后将 head 指向的节点的指针指向上一个节点 pre.
  6. 然后将 pre 指针指向当前的 haed, (作用是:为下一次的迭代做铺垫)
  7. 最后将 head 指向 next 指向的节点. 然后进行下一次循环.
  8. head == null 之后, 返回 pre. 这样就完成了“链表”的翻转.
public static ListNode reverseList(ListNode head) {  
    ListNode pre = null;  
    ListNode next = null;  
    while (head != null) {// 截止条件是head指向null;  
        next = head.next; // 1. 先将next指针指向下一个节点;  
        head.next = pre;  // 2. 然后将head指向的节点的指针指向上一个节点;  
        pre = head;       // 3. 然后将pre指针指向head指向的节点(作用是:为下一次的迭代做铺垫);  
        head = next;      // 4. 最后将head指针指向next指向的节点, 这样就可以进行下一次循环了.  
    }  
    return pre;  
}

3.2 对这个方法进行测试

设置一段链表, 进行测试, 对于这个方法进行实现.

public class MySingleListReverse {  
    // 单链表节点  
    public static class ListNode {  
        public int val;  
        public ListNode next;  
  
        public ListNode(int val) {  
            this.val = val;  
        }  
  
        public ListNode(int val, ListNode next) {  
            this.val = val;  
            this.next = next;  
        }  
    }  
  
    // 反转单链表  
    public static ListNode reverseList(ListNode head) {  
        ListNode pre = null;  
        ListNode next = null;  
        while (head != null) {  
            //注意这里:赋值方面的问题(引用数据类型),  
            //“=”号左边的是你要修改的地方, “=”右边的是你需要指向的地方.  
            next = head.next;  
            //next的问题说明:  
            //若是将带着“next”的放到左边, 说明修改在本身(head)上修改,  
            //若是将带着“next”的放到右边, 说明是将本身指向next指向的位置  
            head.next = pre;  
            pre = head;  
            head = next;  
        }  
        return pre;  
    }  
  
//    public static ListNode reverseList(ListNode head) {  
//        ListNode pre = null;  
//        ListNode next = null;  
//        while (head != null) {// 截止条件是head指向null;  
//            next = head.next; // 1. 先将next指针指向下一个节点;  
//            head.next = pre;  // 2. 然后将head指向的节点的指针指向上一个节点;  
//            pre = head;       // 3. 然后将pre指针指向head指向的节点(作用是:为下一次的迭代做铺垫);  
//            head = next;      // 4. 最后将head指针指向next指向的节点, 这样就可以进行下一次循环了.  
//        }  
//        return pre;  
//    }  
  
  
    // 打印链表  
    public static void printList(ListNode head) {  
        ListNode current = head;  
        while (current != null) {  
            System.out.print(current.val + " ");  
            current = current.next;  
        }  
        System.out.println();  
    }  
  
    public static void main(String[] args) {  
        // 创建一个单链表: 1 -> 2 -> 3 -> 4 -> 5  
        // 第一种方式  
//        ListNode head = new ListNode(1);  
//        head.next = new ListNode(2);  
//        head.next.next = new ListNode(3);  
//        head.next.next.next = new ListNode(4);  
//        head.next.next.next.next = new ListNode(5);  
  
        // 第二种方式  
        ListNode list1 = new ListNode(1);  
        ListNode list2 = new ListNode(2);  
        ListNode list3 = new ListNode(3);  
        ListNode list4 = new ListNode(4);  
        ListNode list5 = new ListNode(5);  
  
        list1.next = list2;  
        list2.next = list3;  
        list3.next = list4;  
        list4.next = list5;  
  
  
        // 打印原始链表  
        System.out.println("原始链表:");  
        printList(list1);  
  
        // 反转链表  
        ListNode reversedHead = reverseList(list1);  
  
        // 打印反转后的链表  
        System.out.println("反转后的链表:");  
        printList(reversedHead);  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值