vector/List 实现 (顺序表与双向循环链表实现)

实现

#include<iostream>
#include<string>
#include<assert.h>
#include <cstring>
using namespace std;
struct TrueType
{

};
struct FalseType
{

};
template <class T>
struct IsPoD
{
  typedef  struct FalseType ispod;
};
template<>
struct IsPoD<int>
{
  typedef  struct TrueType ispod;
};
template<>
struct IsPoD<char>
{
   typedef struct TrueType ispod;
};
template<> struct IsPoD<float>
{
   typedef  struct TrueType ispod;
};
template<> struct IsPoD<long>
{
   typedef  struct TrueType ispod;
};
template <class T>
class SeqList 
{ 
public: 
        SeqList() 
          :_a(nullptr),_size(0),_capacity(0)
        {}
        SeqList(const SeqList<T>& s)
        {
            allocate(_a,s._a,s._size,s._size,typename IsPoD<T>::ispod());   
        }
        SeqList& operator=(SeqList<T>object)
        {
            std::swap(object._a,_a);
            _size = object._size;
            _capacity = object._capacity;
        }
        ~SeqList()
        {
            delete []_a;
        }
        void PushBack(const T& x);
        void PopBack(); 
        void Insert(size_t pos, const T& x); 
        void Erase(size_t pos); 
        T& operator[](size_t pos); 
        void Print();
protected :
        void allocate(T*&dest,T*src,size_t N,size_t size,struct TrueType)
        {
            dest = new T[N];//N代表要申请多少个元素的空间大小,size代表src共有多少个元素 
            memmove(dest,src,size*sizeof(T));
        }
#if 1
        void allocate(T*&dest,T*src,size_t N,size_t size,struct FalseType)
        {
            dest = new T[N];
            for(int i=0;i<size;++i)
            {
                dest[i]=src[i];
            }
        }
#endif
        void CheckCapicity()
        {
            if(_size==_capacity)
            {
               T * tmp=nullptr;
               allocate(tmp,  _a,    _size*2+5,   _size, typename  IsPoD<T>::ispod());   
               delete [] _a;
               _a = tmp;
            }
        }
         
private: 
        T* _a; 
        size_t _size; 
        size_t _capacity; 
}; 
template<class T>
void SeqList<T>::PushBack(const T&x)
{
    CheckCapicity();
    _a[_size++] = x;
}
template<class T>
void SeqList<T>::PopBack()
{
    this->_size--;
}
template<class T>
void SeqList<T>::Insert(size_t pos,const T&x)
{
    CheckCapicity();
    for(size_t i=this->_size-1;i >=pos ; --i)
    {
        _a[i+1] = _a[i];
    }
    _a[pos]=x;
    ++_size;
}
template<class T>
void SeqList<T>::Erase(size_t pos)
{
    for(size_t i=pos;i<this->_size;++i)
    {
        _a[i]=_a[i+1];
    }
    this->_size--; 
}
template<class T>
T& SeqList<T>::operator[](size_t pos)
{
     assert(pos<_size);
     return  _a[pos];
}
template<class T>
void SeqList<T>::Print()
{
    for(int i=0;i<this->_size;++i)
    {
        cout<<this->_a[i]<<endl;
    }
}
#if 1
// 带头节点的双向循环链表--思考结构的优势 
template <class T>
struct ListNode 
{
        ListNode(const T&x=T())
        {
            _data = x;
            _next = nullptr;
            _prev = nullptr;
        }
        ~ListNode()
        {}
        T _data; 
        ListNode* _next; 
        ListNode* _prev; 
}; 

template<class T> 
class List 
{ 
        typedef ListNode<T> Node; 
public: 
        List()
            :_head(nullptr)
        {}
        List(const List& l)
        {
             allocate(_head,l._head);
        }
        List& operator=(const List l)
        {
            std::swap(l._head,_head);
            return *this;
        }
        ~List() 
        {
            Node * pCur = _head;
            Node * prev = nullptr;
            while(prev!=_head) // 哇 写的完美 nullptr 也处理掉了 太开心了,还只进行了一次内存引用 呀咯 无敌勒 
            {
                prev = pCur; // 这个赋值 要处理 只有一个节点的情况
                pCur = pCur -> _next;
                delete  prev;
                prev = pCur;
            }
        }
        void PushBack(const T& x); 
        void PopBack();
        void PushFront(const T& x); 
        void PopFront();
        void Insert(Node* pos, const T& x); 
        void Erase(Node* pos); 
        void Print();
protected:
        void allocate(Node*&Dest,Node*Src)
        {
            if(Dest==nullptr||Dest == Src)
                return ;
            Node * pCur = nullptr;
            Node * prev =nullptr;
            Dest = pCur = prev = new Node(Src);
            Src = Src->_next;
            while(Src)
            {
                pCur = pCur->_next = new Node(Src);
                pCur->_prev = prev;
                prev = pCur;
                Src = Src->_next;
            }
            pCur->_next = Src;
            Src ->_prev = pCur;
        }
private: 
        Node* _head; 
};
template<class T>
void List<T>::PushBack(const T&x)
{
    if(_head==nullptr)
    {
        _head = new Node(x);
        _head->_prev = _head;
        _head->_next = _head;
        return ;
    }
    Node * prev = this->_head->_prev;
    Node * pCur = prev->_next = new Node(x);
    pCur ->_prev = prev;
    pCur ->_next = _head;
    _head ->_prev = pCur;
}
     
template<class T>
void List<T>::Print()
{
    if(_head)
    {
        Node * pCur = _head;
        while(pCur->_next!=_head)
        {
           cout<<pCur->_data<<" ";
           pCur = pCur->_next;
        }
        cout<<pCur->_data;
    }
    cout<<endl;
}
template<class T>
void List<T>::Erase(Node*pos)
{
    assert(pos);
    Node * prev = pos->_prev;
    Node * pnext = pos->_next;
    prev->_next = pnext;
    pnext->_prev = prev;
    delete pos;
    if(_head==pos)
        _head = pnext;
}
template<class T>
void List<T>::Insert(Node*pos,const T&x)
{
    assert(pos);
    Node * prev = pos->_prev;
    Node * pCur = prev->_next = new Node(x);
    pos->_prev = pCur;
    pCur->_prev = prev;
    pCur->_next = pos;
}
template<class T>
void List<T>::PushFront(const T&x)
{
    PushBack(x);
}
template<class T>
void List<T>::PopBack()
{
    assert(_head);
    if(_head==_head->_next)
    {
        delete _head;
        _head = nullptr;
    }
    else
    {
        Node * del = this->_head->_prev;
        Node * prev = del->_prev;
        prev->_next = _head;
        _head->_prev = prev;
        delete del;
    }
}
template<class T>
void List<T>::PopFront()
{
    assert(_head);
    if(_head==_head->_next)
    {
        delete _head;
        _head = nullptr;
        return ;
    }
    Node*Pnext = _head->_next;
    Node*Prev=Pnext->_prev = _head->_prev;
    Prev->_next = Pnext;
    Pnext->_prev = Prev;
    delete _head;
    _head = Pnext;
}
void TestSeqList() 
{ 
        SeqList<string> s2; 
        s2.PushBack("aaaaaaaaaaaaaaaaaaa"); 
        s2.PushBack("bbb"); 
        s2.PushBack("ccc"); 
        s2.PushBack("ddd"); 
        s2.Print();  
        SeqList<int> s3; 
        s3.PushBack(1);
        s3.PushBack(2);
        s3.PushBack(3);
        s3.PushBack(4);
        s3.Print(); 

} 
void TestList()
{
    List<string> s1;
    s1.PushBack("1111");
    s1.PushBack("2222");
    s1.PushBack("3333");
    s1.PushBack("4444");
    s1.PushBack("5555");
    s1.PushBack("6666");
    s1.Print();
    s1.PopBack();
    s1.PopFront();
    s1.PopBack();
    s1.PopBack();
    s1.PopFront();
    s1.PopFront();
    s1.Print();
}
int main()
{
   // TestSeqList();
    TestList();
    return 0;
}

细节

首先STL下的所有容器的构造函数,都是分俩步来进行的。第一步申请内存simple_alloc去做这个东西,第二步填充元素,fill_XX函数来做。这个fill_xx函数做了类型萃取,内置类型直接通过memmove拷贝,ADT类型通过inplacementnew来实现构造。
所谓inplacementnew,置位new表达式就是在已有的内存上构造对象,它是调用了目标类的拷贝构造来完成的对象构造。
析构的时候,也是根据类型萃取,如果是内置类型直接释放,如果是ADT类型会对每个变量都调用其析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值