反转链表 - 简单

*************

C++

topic: 206. 反转链表 - 力扣(LeetCode)

*************

Give the topic an inspection.

|----------------------------------------------------------------------------|
| |

It seems really easy. At very first, I think that I will use reverse cammand to kill this topic. But a few seconds later I found that I am strange about list link. So relearn the basic skills about the list link.

Linked list is a structure. Linked list is used to store data which share the same type. As is known that memary is all to the computer, the linked list donot have to know the size of memory in advance. It has dynamic structure to store the data.

The basic structure of linked list is as follow, just keep it in ur mind.

cpp 复制代码
struct ListNode 
{
    int val;            // 节点存储的值
    ListNode* next;     // 指向下一个节点的指针
    ListNode(int x) : val(x), next(nullptr) {}  // 构造函数
};

Make a linked list 1 -> 2 -> 3

cpp 复制代码
ListNode* head = new ListNode(1);      // 头节点
head->next = new ListNode(2);         // 第二个节点
head->next->next = new ListNode(3);   // 第三个节点

go through linked list.

cpp 复制代码
void printList(Node* head) 
{
    Node* current = head;
    while (current != nullptr) 
    {
        current = current->next;
    }
}

add 0 in the very begin: 0 ->1 -> 2 -> 3

cpp 复制代码
ListNode* newNode = new ListNode(0);
newNode->next = head;  // 新节点指向原头节点
head = newNode;        // 更新头节点
// 链表变为 0 → 1 → 2 → 3

delete 2: 0 ->1 -> 3

cpp 复制代码
ListNode* curr = head;
while (curr->next != nullptr && curr->next->val != 2) 
{
    curr = curr->next;
}
if (curr->next != nullptr) 
{
    ListNode* temp = curr->next;
    curr->next = curr->next->next;  // 跳过待删除节点
    delete temp;                    // 释放内存
}
// 链表变为 0 → 1 → 3

maybe you donot understand why delete the selected node is so camplex, me either. Donot worry about it. I will show me something interesting.

cpp 复制代码
ListNode* head = new ListNode(1);      // 节点1 (val=1)
head->next = new ListNode(2);          // 节点2 (val=2)
head->next->next = new ListNode(3);    // 节点3 (val=3)

head → 1\|next → 2\|next → 3\|next → nullptr

linked list always has head and nullptr, like a zip, head is head, nullptr is end.

if I want to delete ListNode(2), I should find ListNode(1) first.

head → 1\|next → 2\|next → 3\|next → nullptr

cpp 复制代码
// 3. 遍历链表,找到待删除节点的前驱节点
ListNode* curr = head;
while (curr->next != nullptr && curr->next->val != 2) 
{
    curr = curr->next;  // 移动到下一个节点
}

Once ListNode(1) is found, delete 2

cpp 复制代码
// 4. 如果找到待删除节点(curr->next 是节点2)
if (curr->next != nullptr) 
{
    ListNode* temp = curr->next;      // 临时保存节点2的地址
    curr->next = curr->next->next;    // 让节点1直接指向节点3
    delete temp;                      // 释放节点2的内存
}

head → 1\|next → 3\|next → nullptr.

Maybe I will forget how to use the linked list few days later but donot worry, I will learn angain.

Back to the topic.

reverse the linked list, I think make a new linked list, head == nullptr.

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) 
    {
        
        ListNode *previous = nullptr; // 前一个节点,初始化为链表尾部
        ListNode *current  = head; // 当前节点,初始化为链表头
    }
};

reverse\

cpp 复制代码
class Solution {
public:
    ListNode* reverseList(ListNode* head) 
    {
        
        ListNode *previous = nullptr; // 前一个节点,初始化为链表尾部
        ListNode *current  = head; // 当前节点,初始化为链表头

        while (current != nullptr)
        {
            ListNode *nextTemporary = current->next; // 临时变量
            current->next           = previous;
            previous                = current;
            current                 = nextTemporary;
        }

        return previous;
    }
};

for example.

head -> 1 -> 2 -> 3 -> nullptr

prev = nullptr

curr = 1 -> 2 -> 3 -> nullptr

第一次循环:

  1. nextTemp = curr->next → 保存节点2的地址
  2. curr->next = prev → 节点1的next指向nullptr
  3. prev = curr → prev指向节点1
  4. curr = nextTemp → curr指向节点2

prev = 1 -> nullptr

curr = 2 -> 3 -> nullptr

第二次循环:

  1. nextTemp = curr->next → 保存节点3的地址
  2. curr->next = prev → 节点2的next指向节点1
  3. prev = curr → prev指向节点2
  4. curr = nextTemp → curr指向节点3

prev = 2 -> 1 -> nullptr

curr = 3 -> nullptr

第三次循环

  1. nextTemp = curr->next → 保存nullptr
  2. curr->next = prev → 节点3的next指向节点2
  3. prev = curr → prev指向节点3
  4. curr = nextTemp → curr指向nullptr

prev = 3 -> 2 -> 1 -> nullptr

curr = nullptr

相关推荐
jeo陽3 小时前
04-循环实战:素数、最大公约数、级数求和与枚举法
c语言·开发语言·数据结构
slandarer4 小时前
MATLAB | 趣味编程——动态字符串甜甜圈和爱心
数据结构·matlab·趣味编程
UIU1145 小时前
P1003 [NOIP 2011 提高组] 铺地毯
数据结构·c++·算法
爱读书的小胖5 小时前
LeetCode 88. 合并两个有序数组 C 解题分析
c语言·数据结构·算法
inrichtt6 小时前
第七课时:STM32时钟系统揭秘:从零理解时钟树
c语言·数据结构·stm32·单片机·嵌入式硬件
xxwl5856 小时前
区域赛算法模版第四章---数据结构
数据结构·c++·算法
Logic1018 小时前
C语言/数据结构二维数组题解:找出行列O个数均为偶数的格子——奇偶性预处理+二次遍历
c语言·数据结构·算法·二维数组·时间复杂度·动态内存分配·奇偶性
垆边人似月.9 小时前
移动长度 k 子串使字符串变成回文
数据结构·算法
David猪大卫9 小时前
【C++修炼】string类:string类的模拟实现
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
jeo陽10 小时前
05-数组与冒泡排序:第一个数据结构与经典算法
c语言·数据结构·算法