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

    }
}
相关推荐
《雨声》2 小时前
第3章《VTK可视化基础》
开发语言·c++·qt·算法
蚰蜒螟2 小时前
mysql8 C++源码中创建表函数,表字段最大数量限制,表行最大存储限制
c++·mysql
半盏茶香3 小时前
启航数据结构算法之雅舟,悠游C++秘境——单链表之美妙构筑
数据结构·c++·算法
Power++4 小时前
【BUUCTF逆向题】[2019红帽杯]easyRE
c语言·c++·python·网络安全·系统安全·密码学
jf加菲猫6 小时前
11 享元(Flyweight)模式
c++·设计模式·享元模式
E_han6 小时前
7.list
开发语言·汇编·数据结构·c++·算法·list
一个人的幽默6 小时前
java将list转成树结构
java·list
二掌柜,酒来!6 小时前
Java中未检查类型转换的隐患:从List<Map>到List<Student>的映射问题解析
java·list
花落已飘7 小时前
C++单例模式
java·c++·单例模式