C++--list

目录

1.list的介绍和使用

1.1介绍

 1.2使用

构造函数

list iterator

 list capacity

list element access

list modifiers

迭代器失效问题

2.模拟实现 

iterator的模拟实现

成员变量

成员函数

源码包含测试用例 


1.list的介绍和使用

1.1介绍

list - C++ Reference

1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
2. list 的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
3. list forward_list 非常相似:最主要的不同在于 forward_list 是单链表,只能朝前迭代,已让其更简单高效。
4. 与其他的序列式容器相比 (array vector deque) list 通常在任意位置进行插入、移除元素的执行效率更好。
5. 与其他序列式容器相比, list forward_list 最大的缺陷是不支持任意位置的随机访问,比如:要访问 list的第6 个元素,必须从已知的位置 ( 比如头部或者尾部 ) 迭代到该位置,在这段位置上迭代需要线性的时间开销;list 还需要一些额外的空间,以保存每个节点的相关联信息 ( 对于存储类型较小元素的大 list 来说这可能是一个重要的因素)
 1.2使用
构造函数

list iterator
此处,大家可暂时将迭代器理解成一个指针,该指针指向 list 中的某个节点。
【注意】
1. begin end 为正向迭代器,对迭代器执行 ++ 操作,迭代器向后移动
2. rbegin(end) rend(begin) 为反向迭代器,对迭代器执行 ++ 操作,迭代器向前移动
 list capacity

list element access
list modifiers

 push_front

list 首元素前插入值为 val 的元素
pop_front
删除 list 中第一个元素
push_back
list 尾部插入值为 val 的元素
pop_back
删除 list 中最后一个元素
insert
list position 位置中插入值为 val 的元素
erase
删除 list position 位置的元素
swap
交换两个 list 中的元素
clear
清空 list 中的有效元素
迭代器失效问题

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节 点被删除了。因为list的底层结构为带头结点的双向循环链表,因此list中进行插入时是不会导致list的迭代 器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响

2.模拟实现 

iterator的模拟实现

在前面的vector中我们是用原生指针代替迭代器,这里可行吗?list中每个节点的地址不同,不是一块连续的空间,原生指针的操作如++,--达不到我们想要的效果,所以我们需要将list的迭代器定义为一个类模版,进行封装。

成员变量

迭代器中需要一个节点地址成员变量来表示当前迭代器指向哪里

    //List的迭代器类
    template<class T, class Ref, class Ptr>
    class ListIterator
    {
        typedef ListNode<T>* PNode;
        typedef ListIterator<T, Ref, Ptr> Self;
        PNode _pNode;  
    };
成员函数

用节点地址进行构造,迭代器对象进行拷贝构造

        ListIterator(PNode pNode = nullptr) {
            _pNode = pNode;
        }
        ListIterator(const Self& l) {
            _pNode = l._pNode;
        }

我们希望对迭代器进行解引用时访问的是节点的数据,所以我们需要重载它的运算符;->重载可以解决节点的值是结构体等问题

        T& operator*() {
            return _pNode->_val;
        }
        T* operator->() {
            return &(_pNode->_val);
        }

++我们让迭代器中节点的地址指向它的下一个节点的地址,这样就可以遍历list了,--同理,后置++和--需在参数位置加int

        Self& operator++() {
            _pNode = _pNode->_pNext;
            return *this;
        }
        Self operator++(int) {
            Self tmp(*this);
            _pNode = _pNode->_pNext;
            return tmp;
        }
        Self& operator--() {
            _pNode = _pNode->_pPre;
            return *this;
        }
        Self operator--(int) {
            Self tmp(*this);
            _pNode = _pNode->_pPre;
            return tmp;
        }

==和!=

        bool operator!=(const Self& l) {
            return _pNode != l._pNode;
        }
        bool operator==(const Self& l) {
            return _pNode == l._pNode;
        }

list反向迭代器的成员变量就是一个正向迭代器,对反向迭代器的操作只需对其中的正向迭代器做对应的操作即可,下面的代码有实现,可以参考参考

源码包含测试用例 
//.h文件
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;

namespace xxx
{
    // list反向迭代器实现
    template<class Iterator, class Ref, class Ptr>
    struct List_Reverse_iterator
    {
        Iterator _it;
        typedef List_Reverse_iterator<Iterator, Ref, Ptr> Self;
        List_Reverse_iterator(const Iterator& l = Iterator()) {
            _it = l;
        }
        Ref operator*() {
            /*return ((_it._pNode)->_pPre)->_val;*/
            Iterator tmp(_it);
            return *(--tmp);
        }
        Ptr operator->() {
            return (_it.operator->());
        }
        Self& operator++() {
            --_it;
            return *this;
        }
        Self operator++(int) {
            Self tmp(*this);
            _it--;
            return tmp;
        }
        Self& operator--() {
            ++_it;
            return *this;
        }
        Self operator--(int) {
            Self tmp(*this);
            _it++;
            return tmp;
        }
        bool operator!=(const Self& l) {
            return _it != l._it;
        }
        bool operator==(const Self& l) {
            return _it == l;
        }
    };
}

namespace bite
{
    // List的节点类
    template<class T>
    struct ListNode
    {
        ListNode(const T& val = T()) 
            :_pNext(nullptr)
            ,_pPre(nullptr)
            ,_val(val)
        {}

        ListNode<T>* _pPre;
        ListNode<T>* _pNext;
        T _val;
    };


    //List的迭代器类
    template<class T, class Ref, class Ptr>
    class ListIterator
    {
        typedef ListNode<T>* PNode;
        typedef ListIterator<T, Ref, Ptr> Self;
    public:
        ListIterator(PNode pNode = nullptr) {
            _pNode = pNode;
        }
        ListIterator(const Self& l) {
            _pNode = l._pNode;
        }
        T& operator*() {
            return _pNode->_val;
        }
        T* operator->() {
            return &(_pNode->_val);
        }
        Self& operator++() {
            _pNode = _pNode->_pNext;
            return *this;
        }
        Self operator++(int) {
            Self tmp(*this);
            _pNode = _pNode->_pNext;
            return tmp;
        }
        Self& operator--() {
            _pNode = _pNode->_pPre;
            return *this;
        }
        Self operator--(int) {
            Self tmp(*this);
            _pNode = _pNode->_pPre;
            return tmp;
        }
        bool operator!=(const Self& l) {
            return _pNode != l._pNode;
        }
        bool operator==(const Self& l) {
            return _pNode == l._pNode;
        }
        PNode _pNode;  
    };


    //list类
    template<class T>
    class list
    {
        typedef ListNode<T> Node;
        typedef Node* PNode;
    public:
        typedef ListIterator<T, T&, T*> iterator;
        typedef ListIterator<T, const T&, const T*> const_iterator;
        typedef List_Reverse_iterator<iterator, T&, T*> Reverse_iterator;
        typedef List_Reverse_iterator<iterator, const T&, const T*> const_Reverse_iterator;
    public:
        ///
        // List的构造
        list() {
            CreateHead();
        }
        list(int n, const T& value = T()) {
            CreateHead();
            for (int i = 0; i < n; i++) {
                push_back(value);
            }
        }
        template <class Iterator>
        list(Iterator first, Iterator last) {
            CreateHead();
            while (first != last) {
                push_back(*first);
                first++;
            }
        }
        list(const list<T>& l) {
            list<T> tmp(l.begin(), l.end());
            swap(tmp);
        }
        list<T>& operator=(list<T> l) {
            swap(l);
            return *this;
        }
        ~list() {
            iterator it = begin();
            while (it != end()) {
                iterator tmp(it++);
                delete tmp._pNode;
            }
            delete it._pNode;
        }


        ///
        // List Iterator
        iterator begin() {
            return iterator(_pHead->_pNext);
        }
        iterator end() {
            return iterator(_pHead);
        }
        const_iterator begin() const{
            return const_iterator(_pHead->_pNext);
        }
        const_iterator end() const{
            return const_iterator(_pHead);
        }
        // List Reverse_iterator
        Reverse_iterator rbegin() {
            return Reverse_iterator(end());
        }
        Reverse_iterator rend() {
            return Reverse_iterator(begin());
        }
        const_Reverse_iterator rbegin() const{
            return const_Reverse_iterator(end());
        }
        Reverse_iterator rend() const{
            return const_Reverse_iterator(begin());
        }


        ///
        // List Capacity
        size_t size()const {
            size_t size = 0;
            iterator start(_pHead->_pNext);
            iterator end(_pHead);
            while (start != end) {
                size++;
                start++;
            }
            return size;
        }
        bool empty()const {
            return _pHead == _pHead->_pNext;
        }


        
        // List Access
        T& front() {
            assert(!empty());
            return *begin();
        }
        const T& front()const {
            assert(!empty());
            return *begin();
        }
        T& back() {
            assert(!empty());
            return *(--end());
        }
        const T& back()const {
            assert(!empty());
            return *(--end());
        }


        
        // List Modify
        void push_back(const T& val) { 
            insert(end(), val); 
        }
        void pop_back() { erase(--end()); }
        void push_front(const T& val) { insert(begin(), val); }
        void pop_front() { erase(begin()); }
        // 在pos位置前插入值为val的节点
        iterator insert(iterator pos, const T& val) {
            PNode cur = pos._pNode;
            PNode newnode = new Node(val);
            PNode prev = cur->_pPre;
            prev->_pNext = newnode;
            newnode->_pPre = prev;
            newnode->_pNext = cur;
            cur->_pPre = newnode;
            return iterator(newnode);
        }
        // 删除pos位置的节点,返回该节点的下一个位置
        iterator erase(iterator pos) {
            assert(!empty());
            PNode cur = pos._pNode;
            PNode next = cur->_pNext;
            PNode prev = cur->_pPre;
            prev->_pNext = next;
            next->_pPre = prev;
            delete cur;
            return iterator(next);
        }
        void clear();
        void swap(list<T>& l) {
            std::swap(_pHead,l._pHead);
        }
    private:
        void CreateHead() {
            _pHead = new Node();
            _pHead->_pNext = _pHead;
            _pHead->_pPre = _pHead;
        }
        PNode _pHead;
    };
    struct pos {
        int _col;
        int _row;
        pos(int col=0,int row=0)
            :_col(col)
            ,_row(row)
        {}
    };
    void print(const list<int>& l) {
        for (auto e : l) {
            cout << e << " ";
        }
        cout << endl;
    }
    void test_list1() {
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);
        print(l1);
        
        list<int>::iterator it = l1.begin();
        l1.erase(it);
        print(l1);
        
    }
    void test_list2() {
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);
        list<int>::iterator it = l1.begin();
        while (it != l1.end()) {
            cout << *it << " ";
            it++;
        }
        cout << endl;
    }
    void test_list3() {
        list<pos> l1;
        pos p(66, 66);
        l1.push_back({1,2});
        l1.push_back(pos(2,300));
        l1.push_back(p);
        list<pos>::iterator it = l1.begin();
        while (it != l1.end()) {
            cout << it->_col << ":" << it->_row;
            cout << endl;
            it++;
        }
        cout << endl;
    }
    void test_list4() {
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);
        list<int>::Reverse_iterator rit = l1.rbegin();
        while (rit!=l1.rend()) {
            cout << *rit << " ";
            rit++;
        }
        cout << endl;
        list<int>::Reverse_iterator rit1;
    }
    void test_list5() {
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);
        print(l1);
        cout << l1.size();
        cout << endl;
        cout << l1.empty();
        cout << endl;
        cout << l1.front();
        cout << endl;
        cout << l1.back();
    }
    void test_list6() {
        list<int> l1(6,1);
        print(l1);
        list<int> l2(l1.begin(),l1.end());
        print(l2);
        list<int> l3(l2);
        print(l3);
        list<int> l4(6, 2);
        l1.swap(l4);
        print(l1);
    }
    void test_list7() {
        list<int> l1(6, 1);
        list<int> l2(6, 1);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值