vector,list以及迭代器的使用与注意

C++库里提供了顺序表和链表的各种方法,虽然说不一定要能模拟出库里面的各种方法,但是会使用也是一种技能。
vector
vector 就相当于是顺序表,但是它属于可动态增容的顺序表,但同时它也相当于一个容器,这个容器里可以装任何你想要装的数据。同时这里不是单单要介绍顺序表,而是顺序表和迭代器合起来使用。
在顺序表中,使用频率较多的函数就只有几个,模拟实现出来也不是很困难。


#include<assert.h>
#include<string>
#include<iostream>
using namespace std;
#include"TypeTraits.h"

//Vector 和List不一样,一个是数组一个是双向带头的循环链表,在引用和指针方面都有差异

template<class T>
class MyVector
{
public :
    typedef T* Iterator;
    typedef const T* constItrator;
public:
    //构造函数只构造_start即可,释放也只释放_start
    MyVector() :_start(0), _finish(0), _endofstorage(0)
    {
        cout << "构造" << endl;
    }
    void PushBack(const T& x)
    {
        size_t tmp = Capacity() > 0 ? Capacity() * 2 : 3;
        Expand(tmp);
        /*(*_finish) = x;
        _finish++;*/
        Insert(End(), x);
    }
    void Insert(Iterator pos,const T& x)
    {
        //因为迭代器会失效,所以需要记录pos这个位置,以免代码崩溃
        int gap = pos - _start;
        if (_finish == _endofstorage)
        {
            size_t newCapacity = Capacity() > 0 ? Capacity() * 2 : 3;
            Expand(newCapacity);
            pos = _start + gap;
        }
        assert(pos <= _finish);

        Iterator end = _finish - 1;
        while (end >= pos)
        {
            *(end + 1) = *end;
            --end;
        }
        *(pos) = x;
        _finish ++;
    }
    void Expand(size_t n)
    {
        size_t size = Size();
        size_t capacity = Capacity();
        //如果有效数据最后一个等于最后的范围,说明需要开辟空间
        if (n >= capacity)
        {
            T* tmp = new T[n];
            if (_start)
            {
                TypeCopy(tmp, _start, size);
               /*for (size_t i = Begin(); i < End(); i++)
                {
                    *tmp = *_start;
                    tmp++;
                    _start++;
                }*/
            }
            //释放旧的空间,将 指针再指向新的空间即可
            delete[] _start;
            _start = tmp;
            _finish = _start + size;
            _endofstorage = _start + n;
        }
    }
    void Print()
    {
        for (Iterator it = Begin(); it < End(); it++)
        {
            cout << (*it) << " " ;
        }
        cout << endl;
    }

    size_t Size()
    {
        return _finish - _start;
    }
    size_t Capacity()
    {
        return _endofstorage - _start;
    }
    //迭代器的函数

    Iterator Begin()
    {
        return _start;
    }
    Iterator End()
    {
        return _finish;
    }
    //后置++
    Iterator& operator++()
    {
        _start++;
        return *this;
    }
    //前置++
    Iterator operator++(int)
    {
        Iterator it = _start;
        it++;
        return it;
    }
    bool operator==(const Iterator& v)
    {
        return (*this) == v;
    }
    bool operator!=(const Iterator& v)
    {
        return (*this) != v;
    }
private:
    Iterator _start;
    Iterator _finish;
    Iterator _endofstorage;

};
void testVector()
{
    MyVector<int> v;
    v.PushBack(1);
    v.PushBack(2);
    v.PushBack(3);
    v.PushBack(4);
    v.Insert(v.End(), 5);
    v.Print();
}

List
C++中,链表的库函数名称叫List,这里的链表指的是带头的双向链表
简单实现常用的方法为以下:

#include<iostream>
using namespace std;

//实现的List是一个带头的双向循环链表
template <class T>
struct __ListNode
{
     __ListNode<T>* _prev;
     __ListNode<T>* _next;
    T _data;
    __ListNode(const T& x) :_prev(NULL), _next(NULL), _data(x)
    {}
};
//迭代器的实现
template<class T,class Ref,class Ptr>
struct __ListIterator
{
    typedef __ListIterator<T, Ref, Ptr> Self;
    typedef __ListNode<T> Node;
    Node* _node;

    __ListIterator(Node* node) :_node(node)
    {}
    Ref operator*()
    {
        return _node->_data;
    }
    Ptr operator->()
    {
        return &(_node->_data);
    }
    Self& operator++()
    {
        _node = _node->_next;
        return *this;
    }
    Self operator++(int)
    {
        Self tmp(*this);
        _node = _node->_next;
        return tmp;
    }
    Self& operator--()
    {
        _node = _node->_prev;
        return *this;
    }
    Self operator--(int)
    {
        Self tmp(*this);
        _node = _node->_prev;
        return tmp;
    }
    bool operator==(const Self& s)
    {
        return _node == s._node;
    }
    bool operator!=(const Self& s)
    {
        return _node != s._node;
    }
};

//链表的实现
template<class T>
class List
{
    typedef __ListNode<T> Node;
public:
    //重命名链表容器普通迭代器
    typedef __ListIterator<T, T&, T*> Iterator;
    //const迭代器
    typedef __ListIterator<T, const T&, const T*> ConstIterator;
    Iterator Begin()
    {
        return Iterator(_head->_next);
    }
    //返回的是_head,因为最后一个节点也要遍历
    Iterator End()
    {
        return Iterator(_head);
    }
    ConstIterator Begin() const
    {
        return ConstIterator(_head->_next);
    }
    ConstIterator End() const
    {
        return ConstIterator(_head);
    }
    List() 
        :_head(new Node(T()))
    {
        _head->_prev = _head;
        _head->_next = _head;
    }
    void PushBack(const T& x)
    {
        Node* newNode = new Node(x);
        Node* tail = _head->_prev;

        tail->_next = newNode;
        newNode->_prev = tail;
        _head->_prev = newNode;
        newNode->_next = _head;
    }
    void Pop()
    {
        Node* tail = _head->_prev;

        tail->_prev->_next = _head;
        _head->_prev = tail->_prev;

        delete tail;
    }
    //注意迭代器失效的问题
    void Insert(Iterator pos, const T& x)
    {
        Node* newNode = new Node(x);
        //由于接收的是个迭代器,所以要取得迭代器指向的节点
        Node* cur = pos._node;
        //在定义一个NOde型的节点保存pos节点的前一个位子
        Node* prev = cur->_prev;

        prev->_next = newNode;
        newNode->_prev = prev;

        cur->_prev = newNode;
        newNode->_next = pos;
    }
private:
    Node* _head;
};
//打印链表里的数据
void Print(const List<int>& l)
{
    List<int>::ConstIterator it = l.Begin();
    while (it != l.End())
    {
        cout << (*it) << "  ";
        ++it;
    }
    cout << endl;
}
void testList()
{
    List<int> l;
    l.PushBack(1);
    l.PushBack(2);
    l.PushBack(3);
    //l.Pop();
    Print(l);
    //使用迭代器来操作
    List<int>::Iterator it = l.Begin();
    while (it != l.End())
    {
        if ((*it) % 2 != 0)
        {
            cout << (*it) << endl;
        }
        ++it;
    }
}

其实vector ,list都算是stl里面的东西,没有看过原版,也只能照猫画虎的写一点来加深自己对它的理解。STL里面还有几个组件,空间配置器,配接器,算法,以及仿函数,总共有六大组件,剩下的就是上面的容器和迭代器了。
在C++prime里有详细的介绍与使用,在学习C++时参考这个有很大的帮助。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值