• C++侵入式链表


    C++标准模板库中的list是非侵入式的链表,当我们通过对象来删除容器中的对象时,需要从头到尾查找一次得到iterator,最后通过iterator来删除对象。这样删除容器中的对象时比较缓慢,所以就实现了一个侵入式链表。

    intrusive_list.h

    #ifndef _Intrusive_List_H_
    #define _Intrusive_List_H_
    
    // 侵入式链表
    template<class T>
    class intrusive_list {
    public:
        struct Node;
        // 迭代器
        class iterator {
        public:
            iterator(Node* node) : m_node(node) {}
    
            iterator& operator ++() {
                if (m_node)
                    m_node = m_node->m_next;
                return *this;
            }
            iterator& operator --() {
                if (m_node)
                    m_node = m_node->m_prev;
                return *this;
            }
    
            bool operator == (const iterator& iter) { return m_node == iter.m_node; }
            bool operator != (const iterator& iter) { return !operator ==(iter); }
    
            T& operator *() { return *m_node; }
            T* operator ->() { return m_node; }
    
        private:
            Node* m_node;
        };
    
        intrusive_list() : m_head(nullptr), m_tail(nullptr) {}
    
        ~intrusive_list() {
            Node* node = m_head;
            while (node) {
                Node* next = node->m_next;
                delete node;
                node = next;
            }
        }
    
        // 添加对象
        template<class... Args>
        T* add(Args... args) {
            Node* node = new Node(args...);
    
            if (m_head && m_tail) {
                node->m_prev = m_tail;
                m_tail->m_next = node;
                m_tail = node;
            }
            else {
                m_head = node;
                m_tail = node;
            }
            return node;
        }
    
        // 移除对象
        void remove(T* ptr) {
            Node* node = (Node*)ptr;
            assert(node->m_valid);
            if (m_head == node) {
                m_head = m_head->m_next;
            }
            if (m_tail == node) {
                m_tail = m_tail->m_prev;
            }
            if (node->m_prev)
                node->m_prev->m_next = node->m_next;
            if (node->m_next)
                node->m_next->m_prev = node->m_prev;
            delete node;
        }
    
        iterator begin() { return iterator(m_head); }
        iterator end() { return iterator(nullptr); }
    
    private:
        struct Node : public T {
            template<class... Args>
            Node(Args... args) : T(args...), m_valid(true), m_prev(nullptr), m_next(nullptr) {}
    
            bool m_valid;
            Node* m_prev;
            Node* m_next;
        };
    
        Node* m_head;
        Node* m_tail;
    };
    
    #endif

    test.cpp

    int _tmain(int argc, _TCHAR* argv[])
    {
        struct Person {
            Person(const char* name) : m_name(name) {}
    
            std::string m_name;
            int m_age;
        };
    
        intrusive_list<Person> lst;
    
        Person* p0 = lst.add("11");
        lst.add("2");
        lst.add("3");
        lst.add("4");
        lst.add("5");
        Person* p1 = lst.add("6");
    
        lst.remove(p0);
        lst.remove(p1);
        
        for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
            std::cout << iter->m_name << std::endl;
        }
    
        return 0;
    }
  • 相关阅读:
    测试72.思维好题
    pbds:STL平衡树
    测试69。这场因为轻视少了很多分。
    C++ 中的四种类型转换
    C++ 中的static关键字
    codeforces 1269 E K Integers
    P4556 [Vani有约会]雨天的尾巴 (线段树合并)
    P3521 [POI2011]ROT-Tree Rotations (线段树合并)
    codeforces 600E E. Lomsat gelral (线段树合并)
    线段树合并的一些题
  • 原文地址:https://www.cnblogs.com/dongc/p/4908933.html
Copyright © 2020-2023  润新知