链表反转详解图解

在实现反转之前,先回顾链表操作的一些重点。

现链表节点是以下形式:

struct Node {
	int data;
	Node* next;
};

解决链表问题一定要理解深刻,一些要注意的点:

链表中每一个节点都是物理内存中实际存在的,物理节点本身是固定不变的,给定了地址就在那个地址中不会转移、变化等,链表之所以能够添加,删除,反转等,本质是指向这些物理节点的指针节点在移动,即给物理节点赋予的指针是变化的,而我们进行链表操作实际上是操作这些指针节点。

拿一个例子做说明:假设已经建立一个链表,名为list,它也代表链表的头结点:

蓝色方框表示的是物理内存中实际存在的节点,我在方框下方标注了他们所处的内存地址(橙色)。我用名为list的指针(绿色方框)表示指向这片具有逻辑顺序关系的链表。

理解1:一旦链表已经形成,通过对头节点操作,可以索引出链表中所有的节点,并且是基于箭头所指方向进行索引的!也就是说只能说单向的,箭头的含义其实就在于这里-单向。拿这个链表再作解释:

通过

list = list->next

List所指向的节点到了值为2的物理内存上。这样以后,没有建立其他辅助节点指针的条件下,List就再也不具备能力回到值为1的那个物理节点上,这就是单向的意义。List继续可以往后索引。

那么对于链表反转,我们想要实现的就是从上面的链表形式转换成如下的形式,什么改变了,很明显,箭头反过来了。箭头变了,意味着next指向的地址也要反过来!

先给出实现代码:

Node* ReverseList(Node* list)
{
	Node* tmpNode = list;
	Node* preNode = nullptr;
	while (tmpNode)
	{
		Node* nextNode = tmpNode->next;
		tmpNode->next = preNode;
		preNode = tmpNode;
		tmpNode = nextNode;
	}
	list = preNode;
	return list;
}

一条一条语句分析:

Node* tmpNode = list;

增加一个辅助指针,也可以说辅助节点吧,为了方便,后面提的“节点”都表示为“指向节点的指针”,区分物理节点。

Node* preNode = nullptr;

进入循环中依次索引链表中的节点。

1:Node* nextNode = tmpNode->next;

2:tmpNode->next = preNode;

3-4:

        preNode = tmpNode;
        tmpNode = nextNode;

第二次:

        Node* nextNode = tmpNode->next;
        tmpNode->next = preNode;

此时发现,箭头反过来了,这正不是我们想要的,tmpNode和preNode继续往后推,

        preNode = tmpNode;
        tmpNode = nextNode;

现在要做的不就把tmpNode->next指向preNode不就完事了

        Node* nextNode = tmpNode->next;
        tmpNode->next = preNode;

到这里基本上结束了,把preNode赋给list,完成。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值