当前位置: 首页 > article >正文

2.3-STL库中list的模拟实现

2.3-STL库中list的模拟实现

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

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

#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; // 啥也没有。

    }
}

http://www.kler.cn/a/535311.html

相关文章:

  • MySQL万能备份脚本
  • app专项测试(网络测试流程)
  • GNN多任务预测模型实现(二):将EXCEL数据转换为图数据
  • 【Uniapp-Vue3】z-paging插件组件实现触底和下拉加载数据
  • 【重生之学习C语言----杨辉三角篇】
  • 尝试把clang-tidy集成到AWTK项目
  • 10个Redis高阶面试题
  • 尚硅谷课程【笔记】——大数据之Shell【二】
  • SQL LEFT JOIN 详解
  • 【Elasticsearch】post_filter
  • 嵌入式经典面试题之操作系统(三)
  • 洛谷P2367 语文成绩(一维差分模板)
  • Hive自定义函数简介及实践案例
  • C# MAUI 注册服务
  • 如何在本机或服务器上部署运行DeepSeek R1模型
  • 高级java每日一道面试题-2025年01月29日-框架篇[SpringBoot篇]-SpringBoot 实现热部署有哪几种方式?
  • tcp/ip网络协议,tcp/ip网络协议栈
  • RabbitMQ 从入门到精通:从工作模式到集群部署实战(二)
  • Day52:type()函数
  • RocketMQ实战—5.消息重复+乱序+延迟的处理
  • 记录 | WPF基础学习自定义按钮
  • 【matlab代码】平方根扩展卡尔曼滤波(SR EKF)例程,三维非线性系统的滤波
  • 【Rust自学】20.2. 最后的项目:多线程Web服务器
  • 在远程 Linux 服务器上运行 Jupyter Notebook(.ipynb 文件)
  • idea 启动 thingsboard
  • iOS--SDWebImage源码解析