ListNode prev = dummyHead 的作用是什么?

来源:5-1 Leetcode中和链表相关的问题

weixin_慕工程1295506

2019-09-18

老师您好,我有一点看不明白,想问下ListNode prev = dummyHead 这句赋值语句是怎么操作链表的? 因为最后返回的是dummyHead.next,而dummyHead.next = head, 但是所有的检查删除都是在prev上面操作的,最后是怎样把操作结果体现在dummyHead的呢?
这是我的代码,最终判断是错误的,但是我觉得逻辑并没有什么差别,请问问题是出在那句语句吗?谢谢老师

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
	       while(dummyHead.next != null){
	            if(dummyHead.next.val == val)
	                dummyHead.next = dummyHead.next.next;
	            else
	                dummyHead = dummyHead.next;
        }
        return dummyHead;
    }
}
写回答

1回答

liuyubobobo

2019-09-18

以下讲解基于课程 4-5 小节的代码:


ListNode prev = dummyHead 这句话没有操作链表,他只是用一个叫 prev 的变量值,指向了 dummyHead 所指向的内存而已。这句话以后,prev 和 dummyHead 指向了同样的内存空间。


在课程的这段逻辑中:

Node prev = dummyHead;    
for(int i = 0 ; i < index ; i ++)    
    prev = prev.next;

 通过 for 循环,prev 指向了待删除节点的前一个节点。而 dummyHead完全没有动,依旧指向链表头。


下面这段逻辑,真正操纵了链表,将prev指向的下一个节点,从链表中删除了。

Node retNode = prev.next;    
prev.next = retNode.next;

 

但是,上面的逻辑,只动了 prev 所指的下一个节点,没有动 dummyHead。


整个过程,完全是课程 4-5 所演示的动画过程。请在看一遍这个动画,理解一下这个逻辑:https://coding.imooc.com/lesson/207.html#mid=13448


上面说了,这个逻辑其实没有动 dummyHeaad,但怎么体现在了链表上?因为dummyHead是链表的头结点,我们是通过dummyHead,才能访问整个链表的所有元素。这就是链表和数组最大的区别。对于数组,我们可以直接访问数组中的每个元素;但对于链表,我们只能通过头结点,才能访问整个链表的所有元素。


再回头看看我们写的所有链表操作,是不是都是要从 dummyHead 出发,才能进行操作?就是这个道理。


==========


至于你写的代码,问题就是改变了 dummyHead,你可以根据 4-5 的动画,想一下,你的代码运行,绘制成这个动画,到底是什么样子?最终究竟返回了什么?


继续加油!:)

2
1
weixin_慕工程1295506
感谢老师的详细讲解!我现在已经茅塞顿开,再次表示感谢!
2019-09-19
共1条回复

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1704 问题

查看课程