美文网首页
C++ 单链表(不带虚拟头节点)

C++ 单链表(不带虚拟头节点)

作者: 我阿郑 | 来源:发表于2022-01-07 15:01 被阅读0次
image.png
#ifndef SingleLinkedList2_hpp
#define SingleLinkedList2_hpp

#include <iostream>
using namespace std;
#define ELEMENT_NOT_FOUND  -1

template <class T>
class SingleLinkedList;

template <class T>
class SNode {
    // SingleLinkedList<T> 是SNode<T>的一个友类,所以 SingleLinkedList<T> 可以访问SNode<T>的所有成员(尤其是私有成员)
    friend SingleLinkedList<T>;
public:
    SNode(T data, SNode<T> *next):m_data(data), m_next(next) {
        
    }
private:
    T m_data;
    SNode<T> *m_next;
};


template <class T>
class SingleLinkedList {
public:
    SingleLinkedList() {
        m_first = nullptr;
    }
    ~SingleLinkedList() {
        // 析构函数,用于删除链表中的所有节点
        SNode<T> *node;
        while (m_first != nullptr) {
            node = m_first->m_next;
            delete m_first;
            m_first = node;
        }
    }
    
    // 在index位置插入元素
    SingleLinkedList<T>& add(const int index, const T& data) {
        rangeCheckForAdd(index);
        if (index == 0) {
            m_first = new SNode<T>(data, m_first);
        } else {
            SNode<T> *prev = node(index - 1);
            prev->m_next = new SNode<T>(data, prev->m_next);
        }
        m_size++;
        return *this;
    }
    
    SingleLinkedList<T>& add(const T& data) {
        add(m_size, data);
        return *this;
    }
    
    SingleLinkedList<T>& remove(const int index, T&data) {
        rangeCheck(index);
        
        SNode<T> *n = m_first;
        // 删除第一个元素是特殊情况
        if (index == 0) {
            m_first = m_first->m_next;
        } else {
            // 找到前一个元素
            SNode<T> *prev = node(index - 1);
            // 要删除的节点
            n = prev->m_next;
            // 要删除的节点元素
            data = n->m_data;
            // 删除节点
            prev->m_next = n->m_next;
        }
        delete n;
        m_size--;
        return *this;
    }
    
    // 删除链表中的所有节点
    void clear() {
        SNode<T> *node;
        while(m_first != nullptr) {
            node = m_first->m_next;
            delete m_first;
            m_first = node;
        }
        m_size = 0;
    }
    
    // 获取index位置的元素
    // 因为要给data赋值所以这里不能写成 const T& data
    void get(int index, T& data) const {
        SNode<T> *temp = node(index);
        if (temp) {
            data = temp->m_data;
        }
    }
    
    // 更新index位置的元素
    void set(int index, const T& data) const {
        SNode<T> *temp = node(index);
        if (temp) {
            temp->m_data = data;
        }
    }
    
    // 查找元素的索引
    int indexOf(const T& data) {
        SNode<T> *current = m_first;
        int index = 0;
        while (current && current->m_data != data) {
            current = current->m_next;
            index++;
        }
        if (current) {
            return index;
        }
        return ELEMENT_NOT_FOUND;
    }

    bool isEmpty() const {
        return m_size == 0;
    }
    
    int size() const {
        return m_size;
    }
    
    SNode<T>* node(const int index) const {
        rangeCheck(index);
        SNode<T> *node = m_first;
        for (int i = 0; i < index; i++) {
            node = node->m_next;
        }
        return node;
    }

    void output(ostream& out) const {
        SNode<T> *node = m_first;
        while (node) {
            out << node->m_data << ", ";
            node = node->m_next;
        }
    }
    
private:
    SNode<T> *m_first; // 指向第一个节点的指针
    int m_size;
    
    void outOfBounds(int index) const {
        throw index;
    }
    
    void rangeCheck(int index) const {
        if (index < 0 || index >= m_size) {
            outOfBounds(index);
        }
    }
    
    void rangeCheckForAdd(int index) const {
        if (index < 0 || index > m_size) {
            outOfBounds(index);
        }
    }
};

// 重载 <<
template <class T>
ostream& operator<<(ostream& out, const SingleLinkedList<T>& list) {
    list.output(out);
    return out;
}
#endif /* SingleLinkedList2_hpp */

相关文章

  • C++ 单链表(不带虚拟头节点)

  • C++ 单链表(带虚拟头节点)

    为了操作方便,统一所有节点的处理逻辑,可以在最前面增加一个没有实际含义的 虚拟头结点 ,这个虚拟头结点不存储有效数...

  • chap2 线性表-链表

    链表 1. 递归算法,删除不带头节点的单链表中所有值为x的点 2 . 带有头结点的单链表,删除所有值满足特定条件的...

  • 数据结构——链表

    本文所讲的链表是单链表,链表采用无头链表 科普下:一般链表可以分为有头节点的链表与无头节点的链表 有头节点的链表:...

  • 链表-有序单链表合并

    先简单写一下单链表的几个点单链表有带表头节点和不带表头节点两种1)带表头节点 2)不带表头节点 往往使用带表头的会...

  • 线性表

    1.线性表 1.1 顺序表(顺序存储) 静态分配 动态分配 1.2 单链表 单链表定义 不带头节点的单链表插入操作...

  • [数据结构]第二章线性表(3)——单链表

    单链表 什么是单链表? 单链表的定义 别名 注释:或者可以理解为指向头节点的指针既可以表示整个单链表也可以表示头节...

  • 反转链表

    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

  • 反转单链表Java实现

    问题描述 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 解题思路 为了实现反转单链表,...

  • 单链表逆置算法详解

    思路: 首先创建一个单链表,返回一个头节点的指针( head 该头节点不为 NULL,其次进行单链表的逆置设置。具...

网友评论

      本文标题:C++ 单链表(不带虚拟头节点)

      本文链接:https://www.haomeiwen.com/subject/pkfnqrtx.html