递归删除链表节点,引用,删除节点,垃圾回收的关系

来源:2-4 链表与递归

数据结构呆瓜

2023-12-25 13:14:41

https://img1.sycdn.imooc.com/climg/6589081409170ceb08760556.jpg

https://img1.sycdn.imooc.com/climg/65890814094838d507610503.jpg

https://img1.sycdn.imooc.com/climg/658908140923d70505020252.jpg

老师好,内存中最开始的完整链表应该是5->2->3->4->5->6->5

执行完递归写法的removeElement()函数后,再

打印listNode,因为listNode指向了2,所以是2->3->4->6

打印head,因为head从5开始指向,所以是5->2->3->4->6

所以在我整个main函数,既有head指向5->2->3->4->6,又有listNode指向2->3->4->6,但其实两者是同一条链表。只是因为listnNode指向2,head指向5,所以结果不同。那内存里,我的链表到底算是哪个呢,到底删没删5这个头结点呢?我对垃圾回收的概念一直不是很清晰。

写回答

1回答

liuyubobobo

2023-12-26

链表的头指针只有一个。所以,如果你定义的链表的头指针是 head,就是 52346,如果链表的头指针是 listNode,就是 2346。


你给变量起名叫 head,自然头指针是 head。


在更真实的场景中,head 是被保留的,而 listNode 是辅助删除的变量,当删除结束后,listNode 就失效了。


所以,在我们实现的链表中:https://git.imooc.com/class-105/Play-Algorithms-and-Data-Structures/src/master/08-Recursion/08-Recursive-LinkedList/src/LinkedListR.java


head 是在链表内部一直可以访问的,是链表的成员变量。(31 行)


而所有函数内设立的变量,都将在函数结束后结束生命周期。


==========


至于垃圾回收,在你给的例子中,head 和 listNode 都在 main 函数中设立。在 main 函数存在的时候,他们都没有被回收;当 main 函数结束以后,他们都将失效,都将被回收。


在你的例子里,5 这个节点(listNode7)是不会被回收的,因为 listNode7 这个变量在 main 的范围里一直有效,所以一直有引用。


所以,请仔细体会一下我在课程中封装的链表,是不会产生这种情况的。也正是因为这个原因,这种刷题网站是无法涵盖这种工程性的设计的,只是在考察逻辑。但是很多时候,逻辑本身可能是简单的,这种工程的设计才是重点。


更进一步,具体垃圾回收的机制和原理是一个复杂的话题,不在这个课程的范围,如果你做 java 工程师,将来一定会更深入的学习这部分内容的。(包括更深入的理解 JVM 的其他机制。)但在当下,当我们定义 head 是链表的头指针,并且当访问 head 的时候,得到的是我们想要的结果,暂时就 ok 了。


继续加油!:)

1

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2638 学习 · 1091 问题

查看课程