单链表的反转
本文主要介绍头插法逆置和就地逆置法实现链表的反转
1.头插法
1.1思路
迭代方式的链表反转操作核心是从链表头到链表尾
首先让创建一个temp指针使其指向头节点的下一个节点,并将其取出
取出之后让新创建的reverseNode节点指向刚取出的节点,反复进行上述操作。需要注意的是每次取出节点之前,需要用另外一个指针暂存temp指向的节点的下一个节点,防止temp指针变化后找不到新的节点。
最后让初始的头节点指向初始链表中的尾节点。
1.2代码实现
/**
* 反转链表
*/
public void reverseList()
{
//链表为空或者只有一个节点不需要反转直接返回
if (headNode.next == null || headNode.next.next == null)
{
return;
}
//定义一个辅助指针遍历原来的链表
HeroNode temp = headNode.next;
//指向temp指针指向的节点的下个节点
HeroNode next = null;
//新创建的头节点
HeroNode reverseHeadNode = new HeroNode(0,"","");
//遍历原来的链表,每遍历一个节点,就将其取出,放在新的链表reverseHeadNode的最前端
while (temp != null)
{
//暂时保存当前节点的下一个节点,防止变化指针后找不到后续的数据
next = temp.next;
//让temp的下一个节点指向新的链表的最前端
//reverseHeadNode->Null ------> reverseHeadNode->temp->Null
temp.next = reverseHeadNode.next;
reverseHeadNode.next = temp;
//让temp向后移动
temp = next;
}
//将head.next指向reverseHeadNode.next 实现链表的反转
headNode.next = reverseHeadNode.next;
}
2.就地逆置法
就地逆置法与头插法思想类似,唯一区别在于头插法是通过一个新链表头来实现,而就地逆置法是直接通过遍历链表对链表进行修改。
2.1思路
需要额外借助两个指针(begin和end)
-
1.初始状态下让begin指向头节点的下一个节点,end指向begin指向的下一个节点
-
将end指向的节点2从链表取出,添加至链表的头部
- 将end -> begin.next,重复上述操作
此时begin指向的节点已成为链表尾,退出遍历,完成逆置。
2.2代码实现
/**
* 就地逆置法反转链表
*/
public void reverse()
{
//如果链表为空或者链表中只有一个节点则不需要进行操作直接返回即可
if (headNode.next == null || headNode.next.next == null)
{
return;
}
HeroNode begin = headNode.next;
HeroNode end = headNode.next.next;
while (begin != null)
{
//将end所指节点取出,beg指针指向end的下一个节点
begin.next = end.next;
//将end所指节点放入当前链表的头部
end.next = headNode.next;
headNode.next = end;
//将end指向下一个节点
end = begin.next;
}
}