题目
逻辑实现
这里我们采取第二种方式来讲解:
转链表是计算机算法和数据结构中一个常见的题目。链表是一种常见的基础数据结构,它由一系列结点组成,每个结点包含数据域和指向下一个结点的指针。
要反转一个链表,基本的思路是遍历原链表,在遍历过程中改变每个结点的指针方向,使其指向前一个结点,从而得到一个新的链表,其结点的顺序与原链表相反。
下面是反转单向链表的一般步骤:
- 定义三个指针:
pre(前驱结点)、cur(当前结点)和next(下一个结点)。- 将
pre初始化为NULL,它将用来跟踪反转后的链表的末尾。- 从链表的头结点开始,将
cur指向头结点,next指向cur的下一个结点。- 在每次迭代中:
- 将
cur的下一个结点设置为pre,即改变指针方向。- 将
pre向前移动一步,即pre现在指向cur。- 将
cur向前移动一步,即cur现在指向next。- 如果
cur不是链表的最后一个结点,则设置next为cur的下一个结点。- 当
cur变为NULL时,说明已经遍历完整个链表,此时pre指向的就是新的头结点。单趟实现
循环实现
代码实现
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @return ListNode类 */ //三指针解决 //保存上一个节点,当前节点,下一个节点 struct ListNode* ReverseList(struct ListNode* head ) { if(head==NULL) return NULL; // 这里的前后指针初始的时候需要指向空,因为可能存在几种情况,比如是空,prev是当前节点的上一个节点,本身就是空,所以初始的时候需要指向null struct ListNode* cur=head; struct ListNode* prev=NULL; struct ListNode* next=NULL; //这一步放到这里的关键在于,节点的尾部的下一个节点刚好是null,所以放在这个位置,不然导致死循环 while (cur) { next=cur->next; cur->next=prev; prev=cur; cur=next; } //这里需要知道的是,最后cur和next都会越界,所以我们需要返回的数值是prev return prev; }解释:
函数定义:
struct ListNode* ReverseList(struct ListNode* head);这个函数接受一个
ListNode类型的指针head,它是链表的头节点。函数返回一个ListNode类型的指针,即反转后链表的新头节点。空链表检查:
if(head == NULL) return NULL;如果传入的头节点
head是NULL,表示链表为空,直接返回NULL。初始化指针:
struct ListNode* cur = head; struct ListNode* prev = NULL; struct ListNode* next = NULL;
cur用于遍历链表,初始化为头节点。prev指向当前节点的前一个节点,初始化为NULL。next用于临时存储当前节点的下一个节点,初始化为NULL。反转链表:
while (cur) { next = cur->next; cur->next = prev; prev = cur; cur = next; }这是一个循环,遍历原始链表的所有节点:
- 存储当前节点
cur的下一个节点到next。- 将当前节点
cur的next指针指向其前一个节点prev,实现反转。- 将
prev更新为当前节点cur。- 将
cur更新为next,即移动到下一个节点。返回新头节点:
return prev;循环结束后,
prev将指向原始链表的最后一个节点,它成为了反转后链表的新头节点。循环的结束条件: 当
cur为NULL时,循环结束。此时,原始链表的尾节点的next指针已被设置为NULL,避免了死循环。函数的返回值: 函数返回
prev,它是反转后链表的新头节点。这个算法的时间复杂度是 O(n),其中 n 是链表的长度,因为我们需要遍历链表中的每个节点一次。空间复杂度是 O(1),因为我们只使用了有限数量的额外指针变量,不依赖于输入链表的大小。
注意事项
1,
// 这里的前后指针初始的时候需要指向空,因为可能存在几种情况,比如是空,prev是当前节点的上一个节点,本身就是空,所以初始的时候需要指向null
2,
这里需要了解的是,这里我们最后的cur和next都会产生越界行为,所以我们最后返回的是prev
3,
这里的cur->next=prev位置不能放到最后,应该放到第二个,因为我们最后指向的空节点
所以,我们应该先指向上个节点
本文详细介绍了如何反转单向链表,包括基本思路、步骤和C语言代码实现,展示了通过改变结点指针方向来构建新链表的过程。









1918

被折叠的 条评论
为什么被折叠?



