C++ 数据结构超详细讲解单链表

C++ 数据结构超详细讲解单链表

什么是单链表

单链表是一种常见的线性数据结构,它由若干个节点组成,每个节点包含两部分内容:数据域和指针域。其中数据域存储节点所携带的数据,而指针域存储下一个节点的地址。

单链表的性质在于每个节点只有一个指针域,而第一个节点叫做头节点,通常不存放数据,只用来标注链表的起始位置。最后一个节点的指针域指向 NULL,即表示链表的结束。

如何实现单链表

在 C++ 中,我们可以定义一个结构体来表示单链表中的节点,如下所示:

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

有了这个节点结构体,我们就可以创建一个单链表了。在这里,我将实现一个具有常用操作的单链表类,包括节点的插入、删除、遍历等方法,具体实现如下:

class LinkedList {
public:
    LinkedList() : m_head(nullptr), m_size(0) {}
    ~LinkedList() {
        ListNode* temp = m_head;
        while (temp) {
            ListNode* cur = temp;
            temp = temp->next;
            delete cur;
        }
    }

    // 在单链表的开头插入节点
    void addFirst(int val) {
        ListNode* newNode = new ListNode(val);
        newNode->next = m_head;
        m_head = newNode;
        ++m_size;
    }

    // 在单链表的末尾插入节点
    void addLast(int val) {
        ListNode* newNode = new ListNode(val);
        if (m_head == nullptr) {
            m_head = newNode;
        } else {
            ListNode* temp = m_head;
            while (temp->next) {
                temp = temp->next;
            }
            temp->next = newNode;
        }
        ++m_size;
    }

    // 在单链表的指定位置插入节点
    void add(int index, int val) {
        if (index <= 0) {
            addFirst(val);
        } else if (index >= m_size) {
            addLast(val);
        } else {
            ListNode* newNode = new ListNode(val);
            ListNode* p = m_head;
            for (int i = 0; i < index - 1; ++i) {
                p = p->next;
            }
            newNode->next = p->next;
            p->next = newNode;
            ++m_size;
        }
    }

    // 删除单链表的第一个节点
    void removeFirst() {
        if (m_head) {
            ListNode* temp = m_head;
            m_head = m_head->next;
            delete temp;
            --m_size;
        }
    }

    // 删除单链表的最后一个节点
    void removeLast() {
        if (m_head) {
            if (m_head->next == nullptr) {
                delete m_head;
                m_head = nullptr;
            } else {
                ListNode* temp = m_head;
                while (temp->next->next) {
                    temp = temp->next;
                }
                delete temp->next;
                temp->next = nullptr;
            }
            --m_size;
        }
    }

    // 删除单链表的指定位置的节点
    void remove(int index) {
        if (index <= 0) {
            removeFirst();
        } else if (index >= m_size - 1) {
            removeLast();
        } else {
            ListNode* p = m_head;
            for (int i = 0; i < index - 1; ++i) {
                p = p->next;
            }
            ListNode* temp = p->next;
            p->next = temp->next;
            delete temp;
            --m_size;
        }
    }

    // 获取单链表的第一个节点
    ListNode* getFirst() const {
        return m_head;
    }

    // 获取单链表的最后一个节点
    ListNode* getLast() const {
        ListNode* temp = m_head;
        while (temp && temp->next) {
            temp = temp->next;
        }
        return temp;
    }

    // 获取单链表的指定位置的节点
    ListNode* get(int index) const {
        ListNode* p = m_head;
        for (int i = 0; i < index; ++i) {
            p = p->next;
        }
        return p;
    }

    // 获取单链表的节点个数
    int getSize() const {
        return m_size;
    }

    // 打印单链表的值
    void printList() const {
        ListNode* temp = m_head;
        while (temp) {
            std::cout << temp->val << " ";
            temp = temp->next;
        }
        std::cout << std::endl;
    }

private:
    ListNode* m_head; // 链表的头指针
    int m_size; // 链表的节点个数
};

单链表的使用

有了上面实现的单链表类,我们就可以轻松地在程序中使用单链表了。下面是一些使用示例:

示例一:将数组转为单链表

// 将数组转为单链表
LinkedList list;
int nums[] = {1, 2, 3, 4, 5};
int len = sizeof(nums) / sizeof(nums[0]);
for (int i = 0; i < len; ++i) {
    list.addLast(nums[i]);
}
// 打印单链表
list.printList();
// 输出:1 2 3 4 5

示例二:反转单链表

// 反转单链表
ListNode* newHead = nullptr;
ListNode* temp;
while (list.getFirst()) {
    temp = list.getFirst()->next;
    list.getFirst()->next = newHead;
    newHead = list.getFirst();
    list.removeFirst();
}
// 将反转后的结果转为单链表
list.getFirst() = newHead;
// 打印单链表
list.printList();
// 输出:5 4 3 2 1

总结

在 C++ 中实现单链表并不难,只需要用一个节点结构体表示链表中的节点,再用一个类来表示整个单链表,然后实现一些常用操作即可。单链表的操作就是对节点的操作,一定要注意节点为空的情况。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 数据结构超详细讲解单链表 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C语言数据结构之顺序数组的实现

    C语言数据结构之顺序数组的实现 前言 顺序数组是数据结构的一个重要部分,它代表着一种基本的数据结构,能够在数据存储与访问方面发挥极大的作用。本文将详细讲解如何在C语言中实现顺序数组。 简介 顺序数组是在物理内存中顺序存储的一组元素数据,可以通过下标访问任意一个元素。通常情况下,顺序数组的数据类型是相同的,而且每一个元素的大小也是相同的。 实现 实现顺序数组主…

    数据结构 2023年5月17日
    00
  • C++数据结构之搜索二叉树的实现

    C++数据结构之搜索二叉树的实现 搜索二叉树(Binary Search Tree, BST)是一种常见的数据结构,它支持快速地查找、插入和删除元素。本文将详细讲述如何用C++实现搜索二叉树。 一、搜索二叉树的定义 搜索二叉树是一种二叉树,它满足以下性质: 对于任意一个节点,其左子树中的所有节点都小于它,其右子树中的所有节点都大于它; 每个节点的左右子树也都…

    数据结构 2023年5月17日
    00
  • Python数据结构之二叉排序树的定义、查找、插入、构造、删除

    Python数据结构之二叉排序树 一、定义 二叉排序树(Binary Search Tree,BST),也称为二叉查找树或二叉搜索树,是一种基于二叉树的数据结构,其中每个节点都包含一个键值,且满足: 左子树中所有节点的键值均小于当前节点; 右子树中所有节点的键值均大于当前节点; 这是一种自平衡的数据结构,可以快速地进行查找、插入、删除等操作。 二、查找 查找…

    数据结构 2023年5月17日
    00
  • java 数据结构单链表的实现

    Java中实现单链表数据结构通常需要以下几个步骤: 1. 定义节点类 首先需要定义一个节点类,用于表示链表中的一个节点。每个节点包含两个属性:data表示节点的数据,next表示节点的下一个节点。这两个属性都需要定义为public,以便后续操作的访问。 public class Node { public int data; public Node next…

    数据结构 2023年5月17日
    00
  • 【ACM组合数学 | 错排公式】写信

    题目链接:https://ac.nowcoder.com/acm/contest/54484/B 题意很简单,但是数据范围偏大。 错排公式 首先来推导一下错排公式: \[D(n) = n!\sum_{k=0}^{n}\frac{(-1)^k}{k!} \] 设一个函数: \[S_i表示一个排列中p_i = i的方案数 \] 那么我们可以知道: \[D(n) …

    算法与数据结构 2023年4月17日
    00
  • C++数据结构之list详解

    C++数据结构之list详解 什么是list? list是C++ STL库中的一个数据结构,它能够以O(1)的复杂度在任何位置进行插入或删除操作,当然它也支持随机访问指定位置的元素。list属于双向链表,它内部结构为指针连接不同的节点。 如何使用list? 包含头文件 在C++中使用list,需要包含头文件#include <list>。 定义l…

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法之时间空间复杂度入门

    C语言数据结构与算法之时间空间复杂度入门攻略 1. 什么是时间复杂度和空间复杂度? 在进行算法设计时,我们不仅需要考虑到算法的正确性,还要考虑到算法的执行效率。而衡量算法执行效率的指标主要有两个,即时间复杂度和空间复杂度: 时间复杂度:衡量算法所需时间的度量,通常用“大O”符号来表示。比如,对于n个元素的数组,某些算法需要执行n次操作,这个算法的时间复杂度就…

    数据结构 2023年5月16日
    00
  • c++ 数据结构map的使用详解

    c++ 数据结构map的使用详解 什么是map map是C++ STL中提供的一种用以存储键值对(key-value)的容器。它能够以平均O(log n)复杂度进行搜索、插入、删除操作,并且保持元素顺序,是一种比较高效的数据结构。 map的基本用法 定义map 定义map需要包含头文件<map>。 语法:map<key_type, valu…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部