2.3-STL库中list的模拟实现

2.3-STL库中list的模拟实现

list相比于其他的容器,更重要的是它较为复杂的迭代器。

为了能提供可直接运行的代码,接下来的内容在代码块中完成。

cpp 复制代码
#pragma once
#include <iostream>
#include <algorithm>

namespace lst {
    //节点
    template<class T>
    struct list_node {
        list_node<T>* _next;
        list_node<T>* _prev;
        T _data;

        list_node(const T& x = T()) : _next(nullptr), _prev(nullptr) , _data(x){}
        };


    // 封装迭代器
    template<class T, class Ref, class Ptr> // 添加两个模板参数,分别支持引用和指针,实现 const 与非 const 的复用。
    struct __list_iterator
    {
        typedef list_node<T> node;
        typedef __list_iterator<T, Ref, Ptr> self;
        node* _node;

        __list_iterator(node* n) : _node(n){}

        Ref operator*() {
            return _node->_data;
        }

        self& operator++() {
            _node = _node->_next;
            return *this;
        }

        bool operator!=(const self& s) {
            return _node != s._node;
        }

        bool operator==(const self& s) {
            return _node == s._node;
        }

        Ptr operator->() {
            return &_node->_data;            
        }

    };


    template<class T>
    class list {
    public:
        typedef list_node<T> node;
        typedef __list_iterator<T, T&, T*> iterator;
        typedef __list_iterator<T, const T&, const T*> const_iterator;


        // 空初始化
        void empty_inite() { // 值得注意的是,对于 const 对象,依然可以调用此函数。因为 const 对象在初始化之前不具有 const 属性。
            _head = new node;
            _head->_next = _head;
            _head->_prev = _head;
        }
        // 构造函数
        list() {
            empty_inite();
        }

        // 区间构造
        template<class iterator>
        list(iterator first, iterator last) {
            empty_inite();

            while (first != last) {
                push_back(*first);
                ++first;
            }
        }

        void swap(list<T>& tmp) {
            std::swap(_head, tmp._head);
        }


        // 拷贝构造
        list(const list<T>& it) {
            empty_inite();
            list<T> tmp(it.begin(), it.end())
            swap(tmp);
        }

        //赋值重载
        list<T>& operator=(list<T> it) { // 传值传参,获得深拷贝。
            swap(it);
            return *this;
        }

        ~list() {
            clear();
            delete _head;
            _head = nullptr;
        }

        void clear() {
            iterator it = begin();
            while (it != end()) {
                it = erase(it);
            }
        }

        void push_back(const T& x) {
            node* tail = _head->_prev;
            node* new_node = new node(x);
            
            tail->_next = new_node;
            new_node->_prev = tail;

            new_node->_next = _head;
            _head->_prev = new_node;
        }
        

        iterator begin() {
            return iterator(_head->_next);
        }

        iterator end() {
            return iterator(_head);
        }

        const_iterator begin() const{
            return const_iterator(_head->_next);
        }

        const_iterator end() const{
            return const_iterator(_head);
        }


        // 插入
        void insert(iterator pos, T x) {
            node* cur = pos._node;
            node* prev = cur->_prev;

            node* newnode = new node(x);

            prev->_next = newnode;
            newnode->_prev = prev;
            newnode->_next = cur;
            cur->_prev = newnode;
        }
        // 删除
        iterator erase(iterator pos) {
            node* next = pos._node->_next;
            node* prev = pos._node->_prev;

            prev->_next = next;
            next->_prev = prev;

            delete pos._node;
            return iterator(next);
        }
        //此处略过头插,头删,尾删。


    private:
        node* _head;
    };

    template<class T>
    void print_list(const list<T>& l) {
        auto it = l.begin();
        while (it != l.end()) {
            std::cout << *it << " ";
            ++it;
        }
        std::cout << std::endl;
    }

    void test_list1() {
    
    //尾插
    list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    l.push_back(4);
    l.push_back(5);

    // 迭代器。
    list<int>::iterator it = l.begin();
    while (it != l.end()) {
        std::cout << *it << " ";
        ++it;
    }
    std::cout << std::endl;

    // 范围for,只要名字起对了,范围for就天然可用了。
    for(auto e : l) {
        std::cout << e << " ";
    }
    std::cout << std::endl;

    l.push_back(15);

    // 测试const迭代器
    print_list(l); // 1 2 3 4 5 15

}



    void test_list2() {
        list<int> l;
        l.push_back(1);
        l.push_back(1);
        l.push_back(1);
        l.push_back(2);
        l.push_back(1);
        l.push_back(1);
        l.push_back(1);

        for (auto e : l) {
            std::cout << e << " ";
        }        
        std::cout << std::endl;// 1 1 1 2 1 1 1 

        auto pos = l.begin();
        ++pos;
        l.insert(pos, 20); // 1 20 1 1 2 1 1 1 

        for (auto e : l) {
            std::cout << e << " ";
        }      
        std::cout << std::endl;

        l.erase(pos); // 1 20 1 2 1 1 1

        for (auto e : l) {
            std::cout << e << " ";
        }      
        std::cout << std::endl;

        //测试clear
        l.clear();
        std::cout << std::endl; // 啥也没有。

    }
}
相关推荐
键盘会跳舞17 分钟前
C++:std::tuple 源码级深度拆解——变参模板、SFINAE与模板元编程核心技巧
开发语言·c++·sfinae·变参模板
bkspiderx30 分钟前
从零开始:VS Code搭建C/C++开发环境全指南(Windows/macOS/Linux)
c语言·c++·windows·vs code·c/c++开发环境
东华万里31 分钟前
第40篇C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·面试·大学生专区
luj_176844 分钟前
元设计的诱惑与现实
c语言·开发语言·c++·经验分享·算法
小星星闪亮登场1 小时前
ST表--倍增思想
开发语言·数据结构·c++·算法·思维
东华万里1 小时前
第40篇 C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·大学生专区
AC赳赳老秦1 小时前
OpenClaw 多源采集公开行业数据:从原始信息到研究报告初稿的自动化实践
java·c语言·c++·python·php·deepseek·openclaw
玩三国杀玩的1 小时前
Pytorch-c++-CUDA
c++·pytorch·python·深度学习
wangjialelele3 小时前
动态规划DP经典题型总结(Java、C++):路径、子数组、子序列、背包问题详解
java·c++·算法·面试·动态规划·代理模式
牛油果子哥q4 小时前
C++STL算法超全精讲:排序/查找/去重/遍历/最值/合并全套API、仿函数、Lambda适配、实战避坑
开发语言·c++·算法