**假如你有一串糖葫芦(或者一串珠子),每一颗山楂(珠子)都用竹签串起来,一颗连着一颗,这就是链表的样子! 对比我们学过的数组:数组就像一排整齐的小格子,每个格子位置固定;而链表就像手拉手的小朋友,每个人只需要拉着前一个和后一个的手,不用固定站位置,想加人、减人都很方便。 简单定义: 链表是由一个个 “节点”(就像糖葫芦的山楂)组成的,每个节点里装着两样东西:

  1. 我们要存的东西(比如数字、名字);
  2. 一个 “指针”(就像小手),指向旁边的节点。** (二)链表的基本概念(儿童化解释) 术语 生活比喻 简单解释 节点(Node) 糖葫芦的一颗山楂 链表的最小单位,存数据 + 连下一个节点 指针(Pointer) 山楂上的竹签 告诉程序 “下一个节点在哪里” 头节点 糖葫芦的第一个山楂 找到头就能找到整个链表 尾节点 糖葫芦的最后一个山楂 最后一个节点的指针指向 “空” (三)C++ 链表基础代码讲解(一步步拆解)
  3. 先定义 “节点”(糖葫芦的山楂)
#include <iostream>
// 用小朋友能懂的名字,不用复杂命名
using namespace std;

// 定义节点:就像给山楂做模板,每个山楂要有数字,还要有连下一个的“小手”
struct Node {
    int num;       // 节点里存的数字(比如学号、分数)
    Node* next;    // 指向Next(下一个)节点的指针,就是“小手”
};
解释:
•	struct是 C++ 里做 “模板” 的关键字,就像做糖葫芦的模具,每个山楂都按这个样子做;
•	int num:每个节点存一个数字,比如存小朋友的学号 1、2、3;
•	Node* next:这个 “小手” 告诉我们,下一个山楂在哪里,要是最后一个,就指向空(NULL)。
2. 创建第一个节点(串第一颗山楂)

int main() {
    // 1. 创建第一个节点(头节点)
    Node* head = new Node();  // new:做一个新的山楂
    head->num = 1;            // 第一个山楂存数字1
    head->next = NULL;        // 暂时只有一个,小手指向空
    
    // 打印第一个节点的数字,看看对不对
    cout << "第一个节点的数字:" << head->num << endl;
    
    // 记得用完要“清理”,不然电脑会累
    delete head;
    head = NULL;
    
    return 0;
}

运行结果: plaintext 第一个节点的数字:1 解释: • Node* head = new Node():申请内存,做一个新节点,命名为 head(头); • head->num = 1:给这个节点存数字 1(-> 是 C++ 里访问结构体指针里内容的符号,像 “点” 一样); • delete head:用完节点要释放内存,就像吃完糖葫芦把竹签扔垃圾桶,不占地方。 3. 给链表加新节点(串更多山楂)

#include <iostream>
using namespace std;

struct Node {
    int num;
    Node* next;
};

int main() {
    // 1. 创建头节点(第一颗山楂)
    Node* head = new Node();
    head->num = 1;
    head->next = NULL;
    
    // 2. 创建第二个节点(第二颗山楂)
    Node* node2 = new Node();
    node2->num = 2;
    node2->next = NULL;
    // 把第一个节点的小手连到第二个节点
    head->next = node2;
    
    // 3. 创建第三个节点(第三颗山楂)
    Node* node3 = new Node();
    node3->num = 3;
    node3->next = NULL;
    // 把第二个节点的小手连到第三个节点
    node2->next = node3;
    
    // 4. 遍历链表(从头吃到尾,挨个看山楂)
    cout << "链表里的数字:";
    Node* temp = head;  // 用temp当“小手”,从头开始摸
    while (temp != NULL) {  // 只要没摸到最后,就继续
        cout << temp->num << " ";
        temp = temp->next;  // 小手移到下一个节点
    }
    cout << endl;
    
    // 5. 清理内存(吃完收拾)
    delete head;
    delete node2;
    delete node3;
    head = node2 = node3 = NULL;
    
    return 0;
}

运行结果: plaintext 链表里的数字:1 2 3 核心解释: • 新增节点时,要先创建节点,再把前一个节点的next指向新节点; • 遍历链表:用temp临时指针 “代替” 我们遍历,避免直接动head(头节点动了就找不到整个链表了); • while (temp != NULL):只要没到最后一个节点,就继续往下走。 4. 趣味扩展:删除链表中的节点(拿掉一颗山楂)

#include <iostream>
using namespace std;

struct Node {
    int num;
    Node* next;
};

int main() {
    // 1. 创建链表:1 -> 2 -> 3
    Node* head = new Node{1, NULL};
    Node* node2 = new Node{2, NULL};
    Node* node3 = new Node{3, NULL};
    head->next = node2;
    node2->next = node3;
    
    // 2. 删除第二个节点(数字2的山楂)
    cout << "删除前的链表:";
    Node* temp = head;
    while (temp != NULL) {
        cout << temp->num << " ";
        temp = temp->next;
    }
    cout << endl;
    
    // 把第一个节点的小手直接连到第三个节点
    head->next = node3;
    // 删掉第二个节点
    delete node2;
    node2 = NULL;
    
    // 3. 打印删除后的链表
    cout << "删除后的链表:";
    temp = head;
    while (temp != NULL) {
        cout << temp->num << " ";
        temp = temp->next;
    }
    cout << endl;
    
    // 清理剩余节点
    delete head;
    delete node3;
    head = node3 = NULL;
    
    return 0;
}

运行结果: plaintext 删除前的链表:1 2 3 删除后的链表:1 3 解释: 删除节点就像拿掉糖葫芦中间的一颗山楂,只要把前一颗山楂的竹签直接连到后一颗就行,然后把拿掉的山楂 “扔掉”(delete)。

  1. 一定要用new创建节点,用完用delete释放,不然电脑会 “内存泄漏”(就像玩具玩完不收拾,房间会乱);
  2. 头节点很重要,千万别弄丢(就像糖葫芦的头掉了,剩下的就散了);
  3. 指针next最后一定要指向NULL,不然程序会 “乱跑”(就像小朋友找不到回家的路)。 三、总结
  4. 链表就像糖葫芦 / 手拉手的小朋友,由一个个 “节点” 组成,每个节点存数据 + 指向 Next 节点的 “小手”(指针);
  5. C++ 中用struct定义节点,new创建节点、delete释放节点,->访问节点里的内容;
  6. 链表的核心操作:创建节点、连接节点(加节点)、遍历节点(看所有数据)、删除节点,核心是管好 “指针(小手)” 的指向。 (一)先搞懂:什么是 “动态内存分配”?(生活例子 + 简单解释)
  7. 对比 “静态内存”(固定格子) 小豆芽们,我们之前学过这样的代码:

int num = 10; // 静态内存 这就像妈妈提前给你准备了一个固定大小的小抽屉(比如只能放 1 个玩具),不管你用不用,这个抽屉都占着地方,直到程序结束才会被收走。 2. 动态内存分配(按需拿抽屉) new就是动态内存分配,意思是: • 程序运行时,你需要多少空间,就向电脑 “申请” 多少(比如要存 1 个节点,就申请 1 个节点的空间;要存 10 个,就申请 10 个); • 不用的时候,必须用delete把空间 “还回去”,不然电脑的抽屉会被占满,变得很慢。 生活比喻: • 静态内存 = 开学时老师直接给你发了 10 本练习本,不管你用不用完,都只能用这 10 本; • 动态内存(new)= 你需要写作业时,去老师办公室按需领练习本,写完了就把没用完的还回去,其他同学还能接着用。 3. 为什么链表必须用new? 链表的节点数量是不固定的(比如想加 1 个节点、减 1 个节点),静态内存的 “固定抽屉” 满足不了,所以必须用new动态申请空间。 (二)new和delete的核心语法(小学生版) 操作 语法 生活解释 申请单个节点 Node* p = new Node(); 向电脑申请 1 个 “山楂节点” 的抽屉 申请数组 int* arr = new int[5]; 申请 5 个连续的 “数字抽屉” 释放单个节点 delete p; p = NULL; 把 “山楂抽屉” 还回去,清空标记 释放数组 delete[] arr; arr = NULL; 把连续的 “数字抽屉” 批量还回去 关键提醒: • new和delete必须成对使用(领了练习本要还,不然老师会生气😠); • 释放后把指针设为NULL(就像还了练习本后,擦掉本子上你的名字,避免认错)。

0 条评论

目前还没有评论...