如何实现Java单链表反转


本篇内容主要讲解“如何实现Java单链表反转”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现Java单链表反转”吧!单链表的存储结构如图:数据域存放数据元素,指针域存放后继结点地址我们以一条 N1 -> N2 -> N3 -> N4 指向的单链表为例:反转后的链表指向如图:我们在代码中定义如下结点类以方便运行测试:实现思路:从链表头结点出发,依次循环遍历每一个结点,并更改结点对应的指针域,使其指向前一个结点代码如下:测试效果:可以看到,原先指向为 N1 -> N2 -> N3 -> N4 的链表,运行反转方法后,其指向已变为 N4 -> N3 -> N2 -> N1实现思路:从链表头结点出发,依次递归遍历每一个结点,并更改结点对应的指针域,使其指向前一个结点(没免费云主机域名错,实际每一次递归里的处理过程跟上面的循环里是一样的)代码实现:测试效果:注意:在上面的测试代码中,在调用递归函数时传递了Node类的实例head作为参数根据Java中方法调用传参中,基本类型是值传递,对象类型是引用传递可得 =>因为在调用递归函数时传递了head对象的引用,且在递归函数运行过程中,我们已经数次改变了head引用指向的对象,那么当递归函数执行完毕时,head引用指向的对象此时理论上已经是原链表中的尾结点N4了,且链表顺序也已经变成了 N4 -> N3 -> N2 -> N1最终的程序运行结果与我的设想大相径庭!那么,问题出在哪里呢?既然程序运行效果与预期效果不符,那我们就在head对象引用可能发生变化的地方加入注释打印一下对象地址,看看能不能发现问题在哪:加入注释后的代码如下:运行结果:
从上面的运行结果看,在递归函数执行期间,head引用指向的对象确实发生了变化注意调用前/调用返回前/调用后这三个地方head引用指向对象的变化:可以发现,虽然递归函数执行期间确实改变了head引用指向的对象,但实际上是变了个寂寞!函数调用返回后,head引用指向的对象还是调用前的那个!在debug模式下,我们再继续深入看看递归函数调用前跟调用后的head对象是不是完全一样的:从上面两张图可以发现,虽然递归调用前跟调用后head引用指向的对象都是同一个,但这个对象本身的属性(指针域)已经发生了变化!由此说明递归函数的执行并不是在做无用功,而是切切实实改变了原链表的各结点指向顺序!只是因为递归函数执行完成后,并没有成功让传入的head对象引用指向反转后的新链表的头结点N4,此时head对象引用仍然跟调用前一样指向了N1,而N1在反转后的新链表中变成了尾结点,至此,我们已经完美的丢失了反转后的新链表 ,光靠指向尾结点的head根本无法遍历到新链表的其他结点。。。由上面的问题定位可知,问题出在我对Java方法调用中的参数传递理解有偏差,那么接下来就来详细探究一下Java方法调用中的参数传递过程吧!测试示例代码:在上面的示例代码中,我们定义了recursionNode()方法,并在main()方法中调用它方法定义中的headNodeprevNode是形式参数,调用时传入的headnull是实际参数方法定义中的形式参数类型如果是基本数据类型(byte、short、int、long、float、double、boolean、char),则调用方法时,实参到形参的传递实际是值传递,传递的是实际参数值的副本(拷贝)因此,在方法体中任意修改形参的值,并不会影响到方法体外的实参的值方法定义中的形式参数类型如果是对象类型(含基本数据类型的数组),则调用方法时,实参到形参的传递实际也是值传递,传递的是实参对象的引用地址如何理解这个实参对象的引用地址的概念呢?让我们来看看示例代码运行时的内存模型图(简单抽象了stack和heap的部分,如有不对欢迎指正 )如图,main方法和recursionNode方法执行时实际是作为不同的栈帧入栈到当前线程的虚拟机栈中main方法中的 head 引用实际保存的是一个地址,通过这个地址可以找到堆(heap)中的一个Node对象recursionNode方法中的 headNode 引用实际保存的也是一个地址,通过这个地址可以找到堆中的一个Node对象那么在main方法中调用recursionNode方法,实参 head 到形参 headNode 的传递过程中,到底传递的是什么呢?很明显,传递的就是那个能寻址到堆中某个Node对象的地址(划重点,要考!)由此,实参 head 对象引用和形参 headNode 对象引用具有了相同的地址值,指向堆中的同一个Node对象通过这两个引用中的任何一个,都可以改变堆中对应的那个对象的属性和状态理解了对象引用传递的实质后,再回过头来看上面递归方法调用后实际结果与预期结果不一致的问题,一切就迎刃而解了如图,递归调用结束后,虽然递归方法recursionNode()方法体内的 headNode 引用确实已经变成了指向新的Node对象N4,但是main方法中,head 引用指向的仍然是递归方法调用前的Node对象N1(随着递归方法的执行,N1对象内部的指针域已经产生了变化)测试结果:
到此,相信大家对“如何实现Java单链表反转”有了更深的了解,不妨来实际操作一番吧!这里是百云主机网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

相关推荐: Vue中的计算属性与监听属性怎么用

今天小编给大家分享一下Vue中的计算属性与监听属性怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。计算属性:可以理解为能够在里面写一些计算逻…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 08/24 21:05
下一篇 08/24 21:05

相关推荐