模拟实现vector和list 并用list适配出栈,用vector适配出队列

您要的代码已经备好,请准备查收,——————-

MyVector的实现

#pragma once
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
using namespace std;

template <class T>
class Vector
{
public:
    Vector():_start(NULL),_finish(NULL),_endOfstorage(NULL)
    {}
    ~Vector()
    {
        delete []_start;
        _start=_finish=_endOfstorage=NULL;
    }
    size_t Size() const
    {
        return _finish-_start;
    }
    size_t Capacity() const
    {
        return _endOfstorage-_start;
    }

    Vector(const Vector<T> &v);
    Vector<T> operator=(const Vector<T> &v);
    void PushBack(const T & value);
    void PushFront(const T & value);
    void PopFront();
    T & Back();
    T & Front();
    bool Empty();
    void PopBack();
    void Insert(size_t pos,const T & value);
    void Erase(size_t pos);
    void clear();
    void Display();

protected:
    T *_start;
    T *_finish;
    T *_endOfstorage;
    void Expend(size_t n)//扩容可以不作为接口
    {
        if(Capacity()==0)
        {//最开始
            n=3;
        }
        if(n>Capacity())
        {
            size_t size=Size();//这里需要先将size保存下来
            T * tmp=new T[n];
            T * start=tmp;
            T *finish=_start;
            while(finish!=_finish)
            {
                *start=*finish;
                ++start;
                ++finish;
            }//将旧的数据先复制过去
            clear();//清理掉旧的
            _start=tmp;
            _finish=tmp+size;
            _endOfstorage=_start+n;
        }
    }
};
template <class T>
Vector<T>::Vector(const  Vector<T> &v):_start(NULL),_finish(NULL),_endOfstorage(NULL)
{
   _start=new T[v.Size()];
    T *start=_start;
    T *finish=v._start;
    while(finish!=v._finish)
    {
        *start=*finish;
        ++start;
        ++finish;
    }
    //将v中的数据都拷贝进去
    _finish=_start+v.Size();
    _endOfstorage=_finish;
}
template<class T>
Vector<T> Vector<T>:: operator=(const Vector<T> &v)
{
    //采用现代写法,函数结束后会自己调用析构函数
    //采用传统写法
    if(this!=&v)
    {
        Vector<T> tmp(v);
        swap(tmp._start,_start);
        swap(tmp._finish,_finish);
        swap(tmp._endOfstorage,_endOfstorage);
    }
    return *this;
}
template<class T>
void Vector<T>::Insert(size_t pos,const T & value)
{
    if(pos>Size())
    {//Size()位置也是可以进行插入的,为了进行尾插
        return;
    }
    if(Size()>=Capacity())
    {//需要进行扩容
        Expend(Capacity()*2);
    }
    //然后将pos位置后面的数据向后移动
    T *cur=_finish;//这里采用指针的方法是为了避免pos的size_t类型的比较
    while(cur!=_start+pos)
    {
        *cur=*(cur-1);
        --cur;
    }
    _start[pos]=value;
    _finish++;//完成一次插入后需要将_finish后移
}
template<class T>
void Vector<T>:: PushBack(const T & value)
{//这里传参要传引用,因为value若是一个链表或者比较大的数据,传值会进行拷贝构造,代价比较大

    Insert(Size(),value);
}
template<class T>
void Vector<T>::PopBack()
{
    Erase(Size()-1);
}
template<class T>
void Vector<T>::Erase(size_t pos)
{
    if(pos>=Size())
    {
        return;
    }
    if(Size()==0)
    {
        return;
    }
    //将pos位置开始的元素向前移动
    T *cur=_start+pos+1;
    while(cur!=_finish)
    {
        *(cur-1)=*(cur);
        cur++;
    }
    --_finish;//删除一个元素之后需要将_finish向前移动
}

template<class T>
void Vector<T>::PushFront(const T & value)
{
    Insert(0,value);
}

template<class T>
void Vector<T>::PopFront()
{
    Erase(0);
}

template<class T>
T & Vector<T>::Back()//这里没有做是否为空的判断,是因为这个接口是为了给后面的适配器用的
{
    return _start[Size()-1];
}

template<class T>
T & Vector<T>::Front()
{
    return _start[0];
}

template<class T>
bool Vector<T>::Empty()
{
    return _finish==_start;
}

template<class T>
void Vector<T>::clear()
{
    delete[] _start;
    _start=_finish=_endOfstorage=NULL;
}
template<class T>
void Vector<T>::Display()
{
    if(Size()==0)
    {
        return;
    }
    T *cur=_start;
    while(cur!=_finish)
    {
        cout<<*cur<<" ";
        ++cur;
    }
    cout<<endl;
}

MyList的实现

List.h头文件
//这里将头文件和List.cpp文件都应该包含在test.cpp中。模板不支持分离编译
链接一:为什么模板不支持分离编译

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;

template <class T>
struct  Node
{
    T _data;
    Node *_next;
    Node *_prev;
    Node(const T &x):_data(x),_next(NULL),_prev(NULL)
    {}
};
template <class T>
class List
{
public:
    List();//这里头结点用T泛型的匿名变量来初始化
    List(const List<T> &L1);
    List<T> & operator=(const List<T> &L1);
    ~List();
    Node<T> * Insert( Node<T> * pos, const T& x );
    void Erase(Node<T> *pos);
    Node<T> * PushBack( const T &x );
    void PushFront(const T &x);
    void PopBack();
    void PopFront();
    size_t Size() const;
    bool Empty();
    const T & Back()const;
    const T & Front()const;
    void Clear();
    void Display();
protected:
    Node<T> *_head;
};

List.cpp文件

#include "List.h"
template <class T>

    List<T>::List():_head( new Node<T>(T()))//这里头结点用T泛型的匿名变量来初始化
    {
        _head->_next=_head;
        _head->_prev=_head;
    }
template <class T>
    List<T>::List(const List<T> &L1):_head(new Node<T>(T()))
   {
        _head->_next=_head;
        _head->_prev=_head;
        Node<T> *cur=L1._head->_next;
        while(cur!=L1._head)
        {
            PushBack(cur->_data);
            cur=cur->_next;
        }
   }
template <class T>
    List<T> & List<T>::operator=(const List<T> &L1)
   {//TODO
       List<T> L2(L1);//先用L1拷贝构造L2,再将L2和this交换
       swap(this->_head,L2._head);
        //函数调用结束后会自己调析构函数来释放L2即释放旧的this指向的内容
   }
template <class T>
    List<T>::~List()
    {
        Node<T> *cur=_head->_next;
        while(cur!=_head)
        {
            PopBack();
            cur=cur->_next;
        }
        delete _head;
    }
template <class T>
    Node<T> * List<T>::Insert( Node<T> * pos, const T& x )
    {
        assert(pos);
        Node<T> * new_node=new Node<T>(x);
        Node<T> * prev=pos->_prev;

        prev->_next=new_node;
        new_node->_prev=prev;

        new_node->_next=pos;
        pos->_prev=new_node;
        return new_node;
    }
template <class T>
    void List<T>::Erase(Node<T> *pos)
    {
        assert(pos);
        assert(pos!=_head);
        Node<T> * prev=pos->_prev;
        Node<T> * next=pos->_next;

        prev->_next=next;
        next->_prev=prev;
        delete pos;
    }
template <class T>
    Node<T> * List<T>::PushBack( const T &x )
    {
        return Insert(_head,x);
    }
template <class T>
    void List<T>::PushFront(const T &x)
    {
        Insert(_head->_next,x);
    }
template <class T>
    void List<T>::PopBack()
    {
        Erase(_head->_prev);
    }
template <class T>
    void List<T>::PopFront()
    {
        Erase(_head->_next);
    }
template <class T>
    size_t List<T>::Size() const
    {
        size_t count=0;
        Node<T> *cur=_head->_next;
        while(cur!=_head)
        {
            count++;
            cur=cur->_next;
        }
        return count;
    }
template <class T>
    bool List<T>::Empty()
    {
        return _head->_next==_head;
    }
template <class T>
    const T & List<T>::Back()const
    {
        return _head->_prev->_data;
    }
template <class T>
    const T & List<T>::Front()const
    {
        return _head->_next->_data;
    }
template <class T>
    void List<T>::Clear()//清理掉链表中的数据
    {
        Node<T> *cur=_head->_next;
        while(cur!=_head)
        {
            PopBack();
            cur=cur->_next;
        }
        _head->_next=_head;
        _head->_prev=_head;
    }
template <class T>
void List<T>::Display()
{
    Node<T> *cur=_head->_next;
    while(cur!=_head)
    {
        cout<<cur->_data<<" ";
        cur=cur->_next;
    }
    cout<<endl;
}

用List适配出来的栈和用Vector适配出来的队列

Container.h头文件

#pragma once
#include "List.h"
#include "List.cpp"
#include "Vector.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string>
#include <iostream>
using namespace std;

//template<class T,class container>
template<class T,template<class> class container=Vector>
//模板的模板参数,用于和前面的T泛型来保持统一
//并且这里Stack将其缺省值给Vector
class Stack
{
public:
    void Push(const T &x);
    void Pop();
    bool Top(T & tmp);
    size_t Size();
    bool Empty();
    void Display();
protected:
    container<T> _con;//这里要用T来指定类型
};
//template<class T,class container>
template<class T,template<class> class container=List>
//模板的模板参数,用于和前面的T泛型来保持统一
//并且这里Queue将其缺省值给List,便于头删
class Queue
{
public:
    void Push(const T &x);
    void Pop();
    bool Front(T &tmp);
    size_t Size();
    bool Empty();
    void Display();
protected:
    container<T> _con;
};

Container.cpp文件

#include <iostream>
#include "Container.h"

//*********以下是栈的实现************

//template<class T,class container>
template<class T,template<class> class container>
//当使用了模板的模板参数时,这里不可以将其缺省值列出来(类似于函数参数的缺省处理)
void Stack<T,container>::Push(const T &x)
{
    _con.PushFront(x);    
}

//template<class T,class container>
template<class T,template<class> class container>
void Stack<T,container>::Pop()
{
    _con.PopFront();
}

//template<class T,class container>
template<class T,template<class> class container>
bool Stack<T,container>::Top(T & tmp)
{
    if(_con.Empty())
    {
        return false;
    }
    tmp=_con.Front();
    return true;
}

///template<class T,class container>
template<class T,template<class> class container>
size_t Stack<T,container>::Size()
{
    return _con.Size();
}

//template<class T,class container>
template<class T,template<class> class container>
bool Stack<T,container>::Empty()
{
    return _con.Empty();
}

//template<class T,class container>
template<class T,template<class> class container>
void Stack<T,container>::Display()
{
    _con.Display();
}

//*********以下是队列的实现************

//template<class T,class container>
template<class T,template<class> class container>
void Queue<T,container>::Push(const T &x)
{
    _con.PushBack(x);
}

//template<class T,class container>
template<class T,template<class> class container>
void Queue<T,container>::Pop()
{
    _con.PopFront();
}

//template<class T,class container>
template<class T,template<class> class container>
bool Queue<T,container>::Front(T &tmp)
{
    if(Empty())
    {
        return false;
    }
    tmp=_con.Front();
    return true;
}

//template<class T,class container>
template<class T,template<class> class container>
size_t Queue<T,container>::Size()
{
    return _con.Size();
}

//template<class T,class container>
template<class T,template<class> class container>
bool Queue<T,container>::Empty()
{
    return _con.Empty();
}

//template<class T,class container>
template<class T,template<class> class container>
void  Queue<T,container>::Display()
{
     _con.Display();
}

测试代码
test.cpp文件

#include "Container.h"
#include "Container.cpp"


void Test_Stack()
{
    //Stack<int ,Vector<int> > S1;
    Stack<int ,Vector > S1;
    S1.Push(1);
    S1.Push(2);
    S1.Push(3);
    S1.Push(4);
    S1.Push(5);
    cout<<"显示栈中元素"<<endl;
    S1.Display();
    //Stack<int ,Vector<int> > S2(S1);//注意这里后面的空格
    Stack<int ,Vector> S2(S1);

    S2.Display();
    int top=0;
    bool ret=S2.Top(top);
    if(ret==0)
    {
        cout<<"栈为空"<<endl;
    }
    else
    {
        cout<<"栈顶:"<<top<<endl;
    }
    cout<<"出栈3个元素"<<endl;
    S2.Pop();
    S2.Pop();
    S2.Pop();
    S2.Display();
}
void Test_Queue()
{
    //Queue<int ,List<int> > Q1;
    Queue<int ,List > Q1;
    Q1.Push(1);
    Q1.Push(2);
    Q1.Push(3);
    Q1.Push(4);
    Q1.Push(5);
    cout<<"显示队列元素"<<endl;
    Q1.Display();
    //Queue<int ,List<int> > Q2(Q1);
    Queue<int ,List> Q2(Q1);

    Q2.Display();
    int top=0;
    bool ret=Q2.Front(top);
    if(ret==0)
    {
        cout<<"队列为空"<<endl;
    }
    else
    {
        cout<<"对头:"<<top<<endl;
    }
    cout<<"出队列3个元素"<<endl;
    Q2.Pop();
    Q2.Pop();
    Q2.Pop();
    Q2.Display();
    Q2.Pop();
    Q2.Pop();
    cout<<"再出队列2个元素"<<endl;
    ret=Q2.Front(top);
    if(ret==0)
    {
        cout<<"队列为空"<<endl;
    }
    else
    {
        cout<<"对头:"<<top<<endl;
    }
}


int main()
{
    Test_Stack();
    Test_Queue();
    return 0;
}

测试结果:
执行结果

猜你喜欢

转载自blog.csdn.net/Misszhoudandan/article/details/80723545
今日推荐