[C语言数据结构】实现单链表逆转(包含带头结点和不带头结点两种)

一.不带头结点的单链表逆转:

此时只需要设计一个函数即可,无须设计不带头节点的链表输入的主函数。

以下是链表逆转的函数:

list Reverse(list L){
ptrtonode New=NULL,Old=L,tmp;
while(Old){
	tmp=Old->next;
	Old->next=New;
	New=Old;
	Old=tmp;
}
L=New;
return L;	
}

思想是使用两个表(表头)New 和 Old(不知道new和old是否是devc++中的关键词,一开始程序无法运行,后来一顿瞎几把改就能运行了,这里推测new和old是devc++中的关键词)。

tmp作为暂时储存的用于下一次循环中的节点。

新表不断增加节点并调转方向,旧表不断减少节点。当旧表为空时结束循环,最后将L头节点赋予新表表头,即旧表的最后一个元素。

这里可能不好理解,由于备战期末,这次就不画流程图演示了。

第一次循环:设定tmp为2节点,让1结点指向空。并让1节点为新表表头,然后让旧表表头为tmp(2节点)。

第二次循环:设定tmp为3节点,让2结点->next指向1节点。并让2节点为新表表头,然后让旧表表头为tmp(3节点)。

......

最后一次循环:设定tmp为空,让旧表最后一个节点->next指向倒数第二个节点,并让最后一个节点作为新表表头。然后销毁old。

此时将L头节点赋予新表表头,即完成操作,返回反转后的链表list L。

二.带头结点的链表逆转。

带头结点,意味着第一个元素是头节点L->next。

list Reverse(list L){
 if (L == NULL || L->next == NULL) {
        return head;
    }#如果链表不存在或只有头节点,则直接返回。


ptrtonode New=NULL,Old=L->next,tmp;
while(Old){
	tmp=Old->next;
	Old->next=New;
	New=Old;
	Old=tmp;
}
L->next=New;
return L;	
}

此时有一个疑问就是,在第二次循环中,位序为2的节点的->next被设置指向newhead(即位序为1的节点),此时位序为一的节点正在被头节点->next所指。也就是说:位序为2的节点和头节点的->next同时指向位序为1的节点。

求助shitgpt4结果如下:

您的理解是正确的,但有一点需要明确:在反转链表的过程中,头节点的 next 指针不会立即更新。它只在反转过程结束后,即整个链表被反转后,才会更新为指向新的第一个数据节点。

在第二次循环中,的确位序为2的节点的 next 被设置为指向位序为1的节点(即 newHead),但此时头节点仍然指向原链表的第一个数据节点(位序为1的节点)。头节点的 next 只有在整个反转过程完成后才会改变。

也就是说,节点同时被两个指针所指并不会引发问题。只要在循环结束后,让L->next指向新表头就行了。 

这里突然想到另一个问题:如果L->next==new。那么可以说是L指向new还是L->next指向new。

最终答案是:L->next 指向 new

更新一下前面的描述,应该就没问题了,如果有错希望指出,欢迎提问。

除此之外,还有很多种方法逆转单链表,由于备战期末,就不再一一描述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值