C++怎么实现链表

来源:APP编程网作者:菲律宾程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C++怎么实现链表》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么实现链表》有用,将其分享出去将是对创作者最好的鼓励。

链表是一种非连续存储的线性数据结构,由一系列节点组成,每个节点包含数据域和指向下一个节点的指针域,相比数组具有动态扩容、插入删除效率高的特点,是C++数据结构学习的核心内容之一。

C++怎么实现链表

链表的基础结构定义

实现链表首先需要定义节点结构体,节点需要存储数据和下一个节点的地址,我们以存储整型数据的单向链表为例,节点定义如下:

// 定义链表节点结构体
struct ListNode {
    int val;          // 数据域,存储节点值
    ListNode* next;   // 指针域,指向下一个节点
    // 构造函数,初始化节点值和指针
    ListNode(int x) : val(x), next(nullptr) {}
};

链表类的整体设计

我们可以封装一个链表类,包含头节点指针和常用的操作方法,整体类框架如下:

class MyLinkedList {
private:
    ListNode* head;  // 链表头节点
    int size;        // 链表长度
public:
    // 构造函数,初始化空链表
    MyLinkedList();
    // 获取链表中第index个节点的值,索引从0开始
    int get(int index);
    // 在链表头部插入节点
    void addAtHead(int val);
    // 在链表尾部插入节点
    void addAtTail(int val);
    // 在第index个节点前插入值为val的节点
    void addAtIndex(int index, int val);
    // 删除第index个节点
    void deleteAtIndex(int index);
    // 释放链表内存
    ~MyLinkedList();
};

核心方法实现

构造函数与析构函数

构造函数初始化空链表,头节点设为空,长度为0;析构函数需要遍历释放所有节点的内存,避免内存泄漏:

MyLinkedList::MyLinkedList() {
    head = nullptr;
    size = 0;
}

MyLinkedList::~MyLinkedList() {
    ListNode* curr = head;
    while (curr != nullptr) {
        ListNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
}

获取节点值方法

get方法需要先判断索引是否合法,再遍历到对应位置返回节点值:

int MyLinkedList::get(int index) {
    // 索引不合法返回-1
    if (index < 0 || index >= size) {
        return -1;
    }
    ListNode* curr = head;
    // 遍历到索引位置
    for (int i = 0; i < index; i++) {
        curr = curr->next;
    }
    return curr->val;
}

头部插入节点

头部插入只需要创建新节点,让新节点的next指向原来的头节点,再更新头节点即可:

void MyLinkedList::addAtHead(int val) {
    ListNode* newNode = new ListNode(val);
    newNode->next = head;
    head = newNode;
    size++;
}

尾部插入节点

尾部插入需要遍历到最后一个节点,让最后一个节点的next指向新节点:

void MyLinkedList::addAtTail(int val) {
    ListNode* newNode = new ListNode(val);
    // 如果链表为空,直接更新头节点
    if (head == nullptr) {
        head = newNode;
    } else {
        ListNode* curr = head;
        // 遍历到最后一个节点
        while (curr->next != nullptr) {
            curr = curr->next;
        }
        curr->next = newNode;
    }
    size++;
}

指定位置插入节点

指定位置插入需要处理索引为0(头部插入)、索引等于size(尾部插入)和中间插入三种情况:

void MyLinkedList::addAtIndex(int index, int val) {
    // 索引大于长度不插入,索引小于0插入到头部
    if (index > size) return;
    if (index <= 0) {
        addAtHead(val);
        return;
    }
    if (index == size) {
        addAtTail(val);
        return;
    }
    ListNode* newNode = new ListNode(val);
    ListNode* curr = head;
    // 遍历到插入位置的前一个节点
    for (int i = 0; i < index - 1; i++) {
        curr = curr->next;
    }
    newNode->next = curr->next;
    curr->next = newNode;
    size++;
}

删除指定位置节点

删除节点需要先判断索引合法性,再找到待删除节点的前一个节点,修改指针指向后释放内存:

void MyLinkedList::deleteAtIndex(int index) {
    if (index < 0 || index >= size) return;
    ListNode* temp;
    // 删除头节点的情况
    if (index == 0) {
        temp = head;
        head = head->next;
    } else {
        ListNode* curr = head;
        // 遍历到待删除节点的前一个节点
        for (int i = 0; i < index - 1; i++) {
            curr = curr->next;
        }
        temp = curr->next;
        curr->next = temp->next;
    }
    delete temp;
    size--;
}

完整测试示例

我们可以编写测试代码验证链表的功能是否正常:

#include <iostream>
using namespace std;

// 这里放入前面定义的ListNode结构体和MyLinkedList类的所有代码

int main() {
    MyLinkedList* linkedList = new MyLinkedList();
    linkedList->addAtHead(1);
    linkedList->addAtTail(3);
    linkedList->addAtIndex(1, 2);  // 链表变为1->2->3
    cout << linkedList->get(1) << endl;  // 输出2
    linkedList->deleteAtIndex(1);  // 链表变为1->3
    cout << linkedList->get(1) << endl;  // 输出3
    delete linkedList;
    return 0;
}

实现注意事项

  • 操作指针时要注意空指针判断,避免访问空指针导致程序崩溃
  • 动态分配的内存需要在析构函数中释放,防止内存泄漏
  • 插入删除操作时要正确处理指针的指向关系,避免链表断裂
  • 索引相关的操作要先校验合法性,避免越界访问

C++链表数据结构手写链表修改时间:2026-07-21 05:45:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。