先看代码
void SListPopBack(SLNode ** ppHead)
{
assert(*ppHead != NULL);
if ((*ppHead)->next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
SLNode* prev = NULL;//前驱指针
SLNode* end = *ppHead;
while (end->next != NULL)
{
prev = end;
end = end->next;
}
free(end);
end = NULL;
prev->next = NULL;
}
}
prev 的作用:在该段代码中,prev
变量的作用是作为前驱指针,记录当前节点的前一个节点。这是一个辅助指针,用于在单链表中找到需要删除的最后一个节点(即尾节点)并正确地更新链表结构。
当调用SListPopBack
函数时,目的是要删除链表中的最后一个节点。由于单链表只能通过指向下一个节点的指针进行遍历,我们不能直接跳到尾节点,因此需要使用prev
来跟踪当前节点的前驱节点。当找到尾节点后,先将其从链表中删除(通过释放内存并置为NULL),然后将前驱节点的next指针设置为NULL,从而完成对链表的修改。这样可以确保链表正确地移除了最后一个元素。
若没有prev呢?
如果没有prev
变量,在执行删除链表最后一个节点的操作时,我们将无法记录需要删除节点的前一个节点的位置。这样一来,就无法通过修改前一个节点的next指针来断开与最后一个节点的连接,从而无法实现从链表中正确地删除尾节点。
例如,在没有prev
的情况下,当找到尾节点时,虽然我们可以释放其内存,但无法将链表的“新尾部”(即原尾节点的前一个节点)的next指针设为NULL,这会导致链表结构不完整,形成断链或逻辑错误。所以prev
在这里扮演着关键的角色。