反转单链表

现在有一个单向链表如下图所示:

正向链表

反转后如下所示:
反向链表

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    //let [prev, curr] = [null, head];
    let prev = null;
    let curr = head;
    while (curr) {
        let tmp = curr.next;    // 1. 临时存储当前指针后续内容
        curr.next = prev;       // 2. 反转链表
        prev = curr;            // 3. 接收反转结果
        curr = tmp;             // 4. 接回临时存储的后续内容
    }
    return prev;
};

接下来解析反转函数:
反转单向链表1
第一步:next = head.next
将 head.next 赋值给 next 变量,也就是说 next 指向了节点2,先将节点2 保存起来。

第二步:head.next = pre
将 pre 变量赋值给 head.next,即 节点1 指向了 null

第三步:pre = head

将 head 赋值给了 pre,即 pre 指向节点1,将节点1 设为“上一个节点”

第四步:head = next

将 next 赋值给 head,即 head 指向了节点2。将节点2 设为“头节点”

第一次循环完毕,进入第二次循环,如下图
反转单向链表2
第一步:next = head.next
将 head.next 赋值给 next 变量,也就是 next 指向了节点3,先将节点3 保存起来。

第二步:head.next = pre
将 pre 赋值给 head.next,pre 在上一次循环的时候指向了节点1,那么这一步的意义就是节点2 指向了 节点1,完成一次反转

第三步:pre = head

将 head 赋值给了 pre,即 pre 指向节点2,将节点2 设为“上一个节点”

第四步:head = next

将 next 赋值给 head,即 head 指向了节点3。将节点3 设为“头节点”

第二次循环完毕,以此类推!第三次第四次第五次循环。最后反转成如下图
完成反转

总结

  • 保存当前头节点的下一个节点(当前头节点为2,先将节点3 保存起来)

  • 将当前头节点的下一个节点指向 “上一个节点”(当前头节点2 指向了 (“上一个节点”)节点1),这一步才是实现反转

  • 将当前头节点设置 “上一个节点”(将节点2 设为“上一个节点”)

  • 将保存的下一个节点设置 “头节点”(将节点3 设为“头节点”)

在C语言中,可以使用结构体和指针来实现单链表反转。下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 struct Node { int data; struct Node* next; }; // 反转单链表函数 struct Node* reverseLinkedList(struct Node* head) { struct Node* prev = NULL; struct Node* current = head; struct Node* next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } return prev; } // 打印链表函数 void printLinkedList(struct Node* head) { struct Node* temp = head; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); } int main() { // 创建链表节点 struct Node* head = (struct Node*)malloc(sizeof(struct Node)); struct Node* second = (struct Node*)malloc(sizeof(struct Node)); struct Node* third = (struct Node*)malloc(sizeof(struct Node)); // 设置链表节点的值和指针 head->data = 1; head->next = second; second->data = 2; second->next = third; third->data = 3; third->next = NULL; printf("原始链表:"); printLinkedList(head); // 反转链表 head = reverseLinkedList(head); printf("反转后的链表:"); printLinkedList(head); // 释放内存 free(head); free(second); free(third); return 0; } ``` 这段代码中,我们首先定义了一个结构体`Node`,用于表示链表的节点。每个节点包含一个整数类型的数据和一个指向下一个节点的指针。 然后,我们定义了一个`reverseLinkedList`函数,用于反转单链表。该函数使用三个指针变量`prev`、`current`和`next`,分别表示当前节点、前一个节点和下一个节点。通过遍历链表,将当前节点的指针指向前一个节点,实现链表的反转。 最后,在`main`函数中,我们创建了一个简单的链表,并调用`reverseLinkedList`函数进行反转。然后,通过调用`printLinkedList`函数打印出反转后的链表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值