单向链表翻转,之前把这个问题想的太简单了,以为只要把数据域翻转过来就可以了,结果是筐了大瓢,下面举一个简单的例子说明:
假设有n个人站成一排,现在要把这n个人的站的顺序颠倒过来,那么就不能只把这n个人的身高颠倒过来,而是要把每一个人的位置颠倒过来,第一个人站到最后,第二个人站倒数第二,以此类推。
为了检验程序的正确性,这一次我们打印时不能再打印结点数据,而要打印结点。Java程序运行时,JVM为程序开辟了内存空间,每一个结点在栈中都有一个保存的位置,要注意的是,每次程序运行时某一个结点在内存中保存的位置并不是一定的,所以进行方法测试的时候一定要在一次运行中进行测试,这也是之前我一直纠结的问题,为什么打印的结点元素对了,但是结点却不同。
下面来讲解一下我实现链表翻转的过程,在讲解正确方法之前先来看一下假翻转:
public void wrongturn(){ for(int i=1;i<size();i++){ insert(i,get(size()).obj); delete(size()); } }
这里的insert方法详见于我的上一篇博客当中
http://cq520.iteye.com/blog/1860061,这种做法的意思是,先把所有的结点都复制出来,再逆置插入链表中,每次插入之后就把最后一个多出来的结点删除掉,如果你只打印当前的链表元素很容易就被这种方法蒙蔽了,不过很明显,这种做法虽然能够达到逆置的效果,但是逆置的结点却全都变了,就像你换了一帮人来做这件事情一样,它们操作的内存地址不是同一块。
下面讲解正确的方法:
这是一个单链表:
1. 把尾结点放在首结点的前面,把首结点向后推移:
2. 把当前的最后一个结点依次插入到链表的下一个位置:
这句话大家可能有点不理解,其实在执行完第一步之后链表的长度并没变,只是最后一个结点已经变成了之前的倒数第二个结点,然后接下来要做的事情就是把当前的最后一个结点连接到新的头结点后面去(意思就是插入到第二个位置,这个头结点就是没变换前的last结点),执行完这一步之后,最后一个结点又会向前推移,变成倒数第三个结点,再把倒数第三个结点插入到第三个位置以此类推。
代码如下 :
/** * 翻转链表的方法 */ public void turn(){ //先把最后一个结点放在首结点的位置 last.next=head; head=last; //依次从头到尾插入结点 for(int i=1;i<size();i++){ get(size()).next=get(i).next; get(i).next=get(size()); } get(size()).next=null; }
逆置的问题在实现上其实并不难,但是理解起来却并不容易,需要攻克的地方在于不要让同一块内存保存两个数据,也不要让链表中任何一个结点失去引用,而且原来结点在内存中表示也不要改变,这也是结点在引用时最容易看蒙的。
这只是实现翻转的一种方法,当然还有更多的方法等待挖掘,一些朋友们已经写出了其他的方法,希望大家也一起来寻找更多更好的方法。
相关推荐
本文将详细讲解如何在C#中实现单向链表,结合源码解析来帮助你深入理解其内部机制。 首先,我们要知道什么是单向链表。单向链表是由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域存储实际的数据,...
在本文中,我们将深入探讨如何实现单向链表的各种操作,包括建立链表、添加元素、删除元素、翻转链表(包括递归方法)、合并链表、查找链表中的回路以及定位回路的起点。 1. **建立链表** 建立链表通常从创建一个...
单向链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的引用。在编程中,经常需要对链表进行各种操作,其中之一就是逆转链表。逆转链表的操作可以改变链表中节点的顺序,使得原本的...
一种方法是先分别遍历两个链表,记录各自的长度,然后从较长链表的头节点开始,按照长度差向后移动,直到与较短链表的某个节点相遇,那个节点即是交点。另一种方法是使用双指针,让一个指针从头节点开始,另一个指针...
单向链表是最简单的链表类型,其特点是每个节点只能向前遍历,不能向后。在某些情况下,我们需要对链表进行倒序操作,即将链表的顺序反转,例如将A->B->C转换为C->B->A。这个过程是Intel面试中常见的一个问题,旨在...
单向链表是一种基本的数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的引用。在某些情况下,我们可能需要反转链表,即将链表的前后顺序颠倒。本篇文章将详细介绍如何使用递归和非递归两种方法来实现...
翻转链表需要注意的一点是:链表之间靠指针连接,如果贸然将某个节点的next指向其他节点,就有可能造成该节点的丢失,所以翻转链表时(单向或双向),都要注意保存它的周围环境。 时间复杂度:O(n) 空间复杂度:O(1)...
链表分为单向链表和双向链表,前者只能向前遍历,而后者可以向前或向后遍历。在C语言中,实现链表通常涉及定义结构体来表示节点,并提供插入、删除、遍历等操作的函数。 接着,集合(Set)是一种不包含重复元素的...
单链表的各种操作,适合于初学,也适合于复习 单链表操作介绍 1. 创建头节点 ...12. 面试中常见:单链表翻转 13. 已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序,要求用递归方法
1. 单向链表:每个节点只有一个指针,即指向其后继节点,不能向前查找。 2. 循环链表:最后一个节点的指针返回指向第一个节点,形成一个循环。 3. 双向链表:每个节点有两个指针,分别指向前后两个节点,可以双向...
- **类型**:链表分为单向链表、双向链表和循环链表等。 - **特性**: - 动态存储分配,灵活高效。 - 插入、删除操作简单快速。 - 存储空间不连续,不适合随机访问。 #### 知识点二:单向链表反转原理 - **反转...
翻转单向链表 237 删除链表元素 203 删除链表多个元素 206 翻转链表 141 环形链表 2021-05-15: 876 获取链表中间节点 20 判断括号是否成对 2021-05-16: 150后缀表达式 224基本计算器 856计算括号分数 232 用栈实现...
1) **反转单向链表**:实现反转单向链表的算法。 2) **根据值删除节点**:在链表中删除具有特定值的所有节点。 3) **删除倒数节点**:删除链表中的倒数第N个节点。 4) **有序链表去重**:删除链表中的重复元素。 5) ...
对于链表翻转的问题,题目给出了正确答案,这是通过交换当前节点与其后继节点的链接来实现的。这个算法在链表的每个节点上迭代,直到达到尾部,最后将头指针更新为原来的尾节点。 最后,关于JavaScript的题目,删除...
单向链表结构定义如下: struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; 1、翻转链表 递归解法 设置递归函数的返回值为翻转后链表的首节点 递归终止条件为空节点或节点...
单向链表中涉及链表中两个节点需要相互比较的场景 单项链表指针修改(翻转,两侧插入等涉及多点指针修改场景) 常见题目 找到链表的中间节点-快慢指针 翻转链表-pre,op, post多指针 dummy node/哨兵节点 使用场景 ...
8. **判断单向链表是否有环**: - 使用快慢指针(Floyd算法),快指针每次移动两个节点,慢指针每次移动一个节点。如果存在环,快指针最终会追上慢指针;若不存在环,快指针会先到达链表尾部。 9. **判断字符串...
该设计旨在解决约瑟夫环问题,即使用单向循环链表来模拟约瑟夫环的过程,输出各个人的编号。该设计使用了一个链表来存储每个人的编号和密码,并使用循环来实现约瑟夫环的过程。 该设计的主要功能是提供用户从键盘...