C++数据结构的链表实现模拟

C++实现一个简化版的 list 容器,包含主要功能:

双向链表节点结构

cpp 复制代码
template <typename T>
struct ListNode {
    T data;
    ListNode* prev;
    ListNode* next;
    
    ListNode(const T& val = T(), ListNode* p = nullptr, ListNode* n = nullptr)
        : data(val), prev(p), next(n) {}
};

List 类实现

cpp 复制代码
#include <iostream>
#include <initializer_list>

template <typename T>
class List {
private:
    struct Node {
        T data;
        Node* prev;
        Node* next;
        
        Node(const T& val = T(), Node* p = nullptr, Node* n = nullptr)
            : data(val), prev(p), next(n) {}
    };
    
    Node* head;     // 头节点(哨兵节点)
    Node* tail;     // 尾节点(哨兵节点)
    size_t length;  // 元素个数
    
public:
    // 迭代器类
    class iterator {
    private:
        Node* current;
        
    public:
        iterator(Node* node = nullptr) : current(node) {}
        
        T& operator*() { return current->data; }
        const T& operator*() const { return current->data; }
        
        T* operator->() { return &current->data; }
        const T* operator->() const { return &current->data; }
        
        iterator& operator++() {    // 前置++
            current = current->next;
            return *this;
        }
        
        iterator operator++(int) {  // 后置++
            iterator temp = *this;
            current = current->next;
            return temp;
        }
        
        iterator& operator--() {    // 前置--
            current = current->prev;
            return *this;
        }
        
        iterator operator--(int) {  // 后置--
            iterator temp = *this;
            current = current->prev;
            return temp;
        }
        
        bool operator==(const iterator& other) const {
            return current == other.current;
        }
        
        bool operator!=(const iterator& other) const {
            return current != other.current;
        }
        
        friend class List<T>;
    };
    
    // 构造函数
    List() : length(0) {
        // 创建哨兵节点
        head = new Node();
        tail = new Node();
        head->next = tail;
        tail->prev = head;
    }
    
    List(std::initializer_list<T> init) : List() {
        for (const auto& val : init) {
            push_back(val);
        }
    }
    
    // 拷贝构造函数
    List(const List& other) : List() {
        for (auto it = other.begin(); it != other.end(); ++it) {
            push_back(*it);
        }
    }
    
    // 移动构造函数
    List(List&& other) noexcept 
        : head(other.head), tail(other.tail), length(other.length) {
        other.head = nullptr;
        other.tail = nullptr;
        other.length = 0;
    }
    
    // 析构函数
    ~List() {
        clear();
        delete head;
        delete tail;
    }
    
    // 拷贝赋值运算符
    List& operator=(const List& other) {
        if (this != &other) {
            clear();
            for (auto it = other.begin(); it != other.end(); ++it) {
                push_back(*it);
            }
        }
        return *this;
    }
    
    // 移动赋值运算符
    List& operator=(List&& other) noexcept {
        if (this != &other) {
            clear();
            delete head;
            delete tail;
            
            head = other.head;
            tail = other.tail;
            length = other.length;
            
            other.head = nullptr;
            other.tail = nullptr;
            other.length = 0;
        }
        return *this;
    }
    
    // 容量操作
    size_t size() const { return length; }
    bool empty() const { return length == 0; }
    
    // 元素访问
    T& front() {
        if (empty()) throw std::out_of_range("List is empty");
        return head->next->data;
    }
    
    const T& front() const {
        if (empty()) throw std::out_of_range("List is empty");
        return head->next->data;
    }
    
    T& back() {
        if (empty()) throw std::out_of_range("List is empty");
        return tail->prev->data;
    }
    
    const T& back() const {
        if (empty()) throw std::out_of_range("List is empty");
        return tail->prev->data;
    }
    
    // 修改操作
    void push_front(const T& val) {
        insert(begin(), val);
    }
    
    void push_back(const T& val) {
        insert(end(), val);
    }
    
    void pop_front() {
        if (empty()) return;
        erase(begin());
    }
    
    void pop_back() {
        if (empty()) return;
        iterator it = end();
        --it;
        erase(it);
    }
    
    // 插入操作
    iterator insert(iterator pos, const T& val) {
        Node* node = pos.current;
        Node* newNode = new Node(val, node->prev, node);
        
        node->prev->next = newNode;
        node->prev = newNode;
        
        ++length;
        return iterator(newNode);
    }
    
    // 删除操作
    iterator erase(iterator pos) {
        if (pos == end()) return end();
        
        Node* node = pos.current;
        Node* nextNode = node->next;
        
        node->prev->next = node->next;
        node->next->prev = node->prev;
        
        delete node;
        --length;
        
        return iterator(nextNode);
    }
    
    iterator erase(iterator first, iterator last) {
        while (first != last) {
            first = erase(first);
        }
        return last;
    }
    
    void clear() {
        erase(begin(), end());
    }
    
    // 迭代器
    iterator begin() { return iterator(head->next); }
    iterator end() { return iterator(tail); }
    
    // const 迭代器
    class const_iterator {
    private:
        const Node* current;
        
    public:
        const_iterator(const Node* node = nullptr) : current(node) {}
        
        const T& operator*() const { return current->data; }
        const T* operator->() const { return &current->data; }
        
        const_iterator& operator++() {
            current = current->next;
            return *this;
        }
        
        const_iterator operator++(int) {
            const_iterator temp = *this;
            current = current->next;
            return temp;
        }
        
        bool operator==(const const_iterator& other) const {
            return current == other.current;
        }
        
        bool operator!=(const const_iterator& other) const {
            return current != other.current;
        }
    };
    
    const_iterator begin() const { return const_iterator(head->next); }
    const_iterator end() const { return const_iterator(tail); }
    
    // 其他操作
    void reverse() {
        if (length <= 1) return;
        
        Node* current = head->next;
        while (current != tail) {
            std::swap(current->prev, current->next);
            current = current->prev;  // 注意:这里已经交换了prev和next
        }
        
        std::swap(head->next, tail->prev);
        head->next->prev = head;
        tail->prev->next = tail;
    }
    
    void remove(const T& val) {
        iterator it = begin();
        while (it != end()) {
            if (*it == val) {
                it = erase(it);
            } else {
                ++it;
            }
        }
    }
    
    template<typename Predicate>
    void remove_if(Predicate pred) {
        iterator it = begin();
        while (it != end()) {
            if (pred(*it)) {
                it = erase(it);
            } else {
                ++it;
            }
        }
    }
    
    void unique() {
        if (length <= 1) return;
        
        iterator current = begin();
        iterator next = current;
        ++next;
        
        while (next != end()) {
            if (*current == *next) {
                next = erase(next);
            } else {
                current = next;
                ++next;
            }
        }
    }
};

测试示例

cpp 复制代码
int main() {
    // 创建列表
    List<int> lst = {1, 2, 3, 4, 5};
    
    // 测试基本操作
    std::cout << "Original list: ";
    for (auto it = lst.begin(); it != lst.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    
    // 添加元素
    lst.push_front(0);
    lst.push_back(6);
    std::cout << "After push: ";
    for (auto val : lst) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    
    // 删除元素
    lst.pop_front();
    lst.pop_back();
    std::cout << "After pop: ";
    for (auto val : lst) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    
    // 插入和删除
    auto it = lst.begin();
    ++it; ++it;
    lst.insert(it, 99);
    
    it = lst.begin();
    ++it;
    lst.erase(it);
    
    std::cout << "After insert/erase: ";
    for (auto val : lst) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    
    // 反转
    lst.reverse();
    std::cout << "After reverse: ";
    for (auto val : lst) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    
    // 移除特定值
    lst.push_back(3);
    lst.push_back(3);
    lst.remove(3);
    std::cout << "After remove(3): ";
    for (auto val : lst) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

实现特点:

  1. 哨兵节点设计:
    · head 和 tail 作为边界标记
    · 简化边界条件处理
  2. 内存管理:
    · 遵循RAII原则
    · 正确释放所有节点内存
  3. 迭代器支持:
    · 支持前向和后向遍历
    · 实现const迭代器
  4. 主要操作:
    · push_front/push_back: O(1)
    · pop_front/pop_back: O(1)
    · insert/erase (已知位置): O(1)
    · size/empty: O(1)
  5. 异常安全:
    · 基础版本提供基本异常安全保证

这只是一个简化的模拟版本,完整的STL list还需要实现反向迭代器、allocator支持、异常安全保证等更多功能。

相关推荐
biter down2 小时前
C++ 组合与继承:从设计本质到实战,吃透高内聚低耦合
开发语言·c++
fantasy5_52 小时前
C++11 核心特性实战博客
java·开发语言·c++
天若有情6732 小时前
从构造函数到Vue3响应式:C++中“常量转特殊类型”的隐藏大招
开发语言·c++
qq_433554543 小时前
C++ 进阶动态规划(小明的背包3)
开发语言·c++·动态规划
YouEmbedded3 小时前
解码继承——代码复用与层次化设计
开发语言·c++·继承
有点。3 小时前
C++ ⼀级 2023 年 12 ⽉
c++
FMRbpm3 小时前
顺序表实现队列
数据结构·c++·算法·新手入门
飞天狗1113 小时前
G. Mukhammadali and the Smooth Array
数据结构·c++·算法
罗湖老棍子3 小时前
Knight Moves(信息学奥赛一本通- P1257)
c++·算法·bfs