C++ 模板实现Vector和双向链表

本文介绍了一种使用模板来实现Vector类和双向链表的具体方法。Vector类支持多种操作,如插入、删除、调整大小等,并且适用于内置类型和自定义类型。双向链表则实现了基本的链表操作,包括前插、后插、查找和删除等。这两个数据结构均采用泛型编程以提高代码复用率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模板实现Vector

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
using namespace std;

template<class T>
class Vector
{
public:
    Vector()
        :_pData(new T[3])
        ,_size(0)
        ,_capacity(3)
    {}

    Vector(size_t n, const T& data)
    {
        while(n--)
        {
            Check_capacity();
            _pData[_size++] = data;
        }
    }

    Vector(const Vector& v)
        :_pData(new T[strlen(v._pData)+1])
        ,_size(v._size)
        ,_capacity(v._capacity)
    {
        strcpy(_pData, v._pData);
    }

    Vector& operator =(Vector v)
    {
        Swap(*this, v);
        return *this;
    }

    ~Vector()
    {
        if(_pData != NULL)
        {
            delete[] _pData;
            _pData = NULL;
        }
    }

    void Swap(Vector& v)
    {
        std::swap(_pData, v._pData);
        std::swap(_size, v._size);
        std::swap(_capacity, v._capacity);
    }

    void PushBack(const T& data)
    {
            Check_capacity();
            _pData[_size++] = data;
    }

    void PopBack()
    {
        if(_size != 0)
            _size--;
    }

    void PushFront(const T& data)
    {
        Check_capacity();
        for(size_t i = _size; i > 0; i--)
        {
            _pData[i] = _pData[i-1];
        }
        _pData[0] = data;
        _size++;
    }

    void PopFront()
    {
        assert(_size);
        for(size_t i = 1; i < _size-1; i++)
        {
            _pData[i-1] = _pData[i];
        }
        _size--;
    }

    void Insert(size_t pos, const T& data)
    {
        assert(_size && pos>=0 && pos<=_size);
        Check_capacity();
        for(size_t i = _size; i > pos; i--)
        {
            _pData[i] = _pData[i-1];
        }
        _pData[pos] = data;
        _size++;
    }

    void Erase(size_t pos)
    {
        assert(_size);
        assert(_size && pos>=0 && pos<_size);
        for(size_t i = pos; i < _size-1; i++)
        {
            _pData[i] = _pData[i+1];
        }
        _size--;
    }

    void Assign(size_t n, const T& data)
    {
        _size = 0;
        while(n--)
        {
            Check_capacity();
            _pData[_size++] = data;
        }
    }
    void Clear()
    {
        delete[] _pData;
        _pData = NULL;
    }

    T& operator [](size_t index)
    {
        assert(index < _size);
        return _pData[index];
    }

    const T& operator [](size_t index)const
    {
        assert(indec < _size);
        return _pData[index];
    }

    T& Front()
    {
        return _pData[0];
    }

    const T& Front()const
    {
        return _pData[0];
    }

    T& Back()
    {
        return _pData[_size-1];
    }

    const T& Back()const
    {
        return _pData[_size-1];
    }

    size_t Size()const
    {
        return _size;
    }

    size_t Capacity()const
    {
        return _capacity;
    }

    bool Empty()const
    {
        return _size == 0;
    }
    void ReSize(size_t sz, const T& data = T())
    {
        if(_size > sz)
        {
            _size = sz;
        }
        else if(_size < sz)
        {
            while(sz > _size)
            {
                Check_capacity();
                _pData[_size++] = T();
            }
        }
    }

    void Reserve(size_t n)
    {
        size_t tmp = _size;
        while(_size < n)
        {
            Check_capacity();
            _size++;
        }
        _size = tmp;
    }

    void Print()const
    {
        if(_pData != NULL)
        {
            for(size_t i = 0; i < _size; i++)
            {
                cout<<_pData[i]<<"  ";
            }
            cout<<endl;
        }
        else
            cout<<"NULL"<<endl;
    }

    void Print_String()const
    {
        if(_pData != NULL)
        {
            for(size_t i = 0; i < _size; i++)
            {
                cout<<(*(_pData+i)).Pri()<<"  ";
            }
            cout<<endl;
        }
        else
            cout<<"NULL"<<endl;
    }

private:
    void Check_capacity()
    {
        if(_size >= _capacity)
        {
            T* newpData = new T[_size*2];

            //1.深拷贝,调用的时赋值运算符重载operator=
            for(size_t i = 0; i < _size; i++)
            {
                newpData[i] = _pData[i];
            }
            delete[] _pData;
            _pData = newpData;
            _capacity = _size*2;

            ////2.浅拷贝,自定义类型设计资源时,可能会出错,思考
            //memcpy(_pData, newpData, sizeof(T)*_size);
            //_pData = newpData;
        }
    }

    T* _pData;
    size_t _size;
    size_t _capacity;
};

class String
{
public:
    String(const char* str = "")
        :_str(new char[strlen(str)+1])
    {
        strcpy(_str, str);
    }

    String(const String& s)
        :_str(new char[strlen(s._str)+1])
    {
        strcpy(_str, s._str);
    }

    String& operator =(String s)
    {
        swap(_str, s._str);
        return *this;
    }

    char* Pri()const
    {
        return _str;
    }

    ~String()
    {
            delete[] _str;
            _str = NULL;
    }
private:
    char* _str;
};

void Test1()
{
    Vector <int>v;
    v.PushBack(1);
    v.PushBack(2);
    v.PushBack(3);
    v.PushBack(4);
    v.Print();

    v.PopBack();
    v.Print();

    v.PushFront(0);
    v.Print();

    v.PopFront();
    v.Print();

    v.Insert(0, 5);
    v.Print();

    v.Erase(0);
    v.Print();

    cout<<v.Front()<<endl;
    cout<<v[1]<<endl;
    cout<<v.Back()<<endl;

    cout<<v.Size()<<endl;
    cout<<v.Capacity()<<endl;
    cout<<v.Empty()<<endl;

    v.ReSize(2);
    v.Print();

    v.ReSize(10, 0);
    v.Print();

    v.Reserve(5);
    v.Print();

    v.Assign(5, 0);
    v.Print();

    v.Clear();
    v.Print();
}

void Test2()
{
    Vector<String> v;
    v.PushBack("aaaa");
    v.PushBack("bbbb");
    v.PushBack("cccc");
    v.PushBack("dddd");
    v.Print_String();

    v.PopBack();
    v.Print_String();

    v.PushFront("1111");
    v.Print_String();

    v.PopFront();
    v.Print_String();

}

int main()
{
    Test1();//内置类型
    Test2();//类类型
    return 0;
}

这里写图片描述

模板实现双向链表

(头节点不保存数据,不记作有效节点)
#include <iostream>
#include <assert.h>
using namespace std;

template<class T>
struct Node
{
public:
    Node(const T& data = T())
        :_Next(NULL)
        ,_Pre(NULL)
        ,_data(data)
    {}
public:
    Node<T>* _Next;
    Node<T>* _Pre;
    T _data;
};

template<class T>
class List
{
public:
    List()
        :_pHead(new Node<T>)//构造给出头节点(没有有效data)
    {
        _pHead->_Next = _pHead;
        _pHead->_Pre = _pHead;
    }

    List(size_t n, const T& data)
        :_pHead(new Node<T>)//头节点(没有有效data)
    {
        while(n--)
        {
            PushBack(data);
        }
    }

    List(const List& L)
        :_pHead(new Node<T>)
    {
        _pHead->_Next = _pHead;
        _pHead->_Pre = _pHead;
        Node<T>* tmp = L._pHead->Next;
        while(tmp != _pHead)
        {
            PushBack(tmp->_data);
            tmp = tmp->_Next;
        }
    }

    ~List()
    {
        if(_pHead->_Next != _pHead)
        {
            Clear();
        }
        delete[] _pHead;
    }

    void PushBack(const T& data)
    {
        Node<T>* newEnd = CreatNode(data);
        _pHead->_Pre->_Next = newEnd;
        newEnd->_Pre = _pHead->_Pre;
        _pHead->_Pre = newEnd;
        newEnd->_Next = _pHead;
    }

    void PopBack()
    {
        if(_pHead->_Next != _pHead)
        {
            Node<T>* end = _pHead->_Pre;
            _pHead->_Pre = end->_Pre;
            end->_Pre->_Next = _pHead;
            delete[] end;
        }
    }

    void PushFront(const T& data)
    {
        Node<T>* newFront = CreatNode(data);
        _pHead->_Next->_Pre = newFront;
        newFront->_Next = _pHead->_Next;
        _pHead->_Next = newFront;
        newFront->_Pre = _pHead;
    }

    void PopFront()
    {
        if(_pHead->_Next != _pHead)
        {
            Node<T>* tmp = _pHead->_Next;
            _pHead->_Next = tmp->_Next;
            tmp->_Next->_Pre = _pHead;
            delete[] tmp;
        }
    }

    Node<T>* Find(const T& data)
    {
        Node<T>* tmp = _pHead->_Next;
        while(tmp != _pHead)
        {
            if(tmp->_data == data)
                return tmp;
            tmp = tmp->_Next;
        }
        return NULL;
    }

    void Insert(Node<T>* pos, const T& data)
    {
        assert(pos);

        Node<T>* tmp = CreatNode(data);
        tmp->_Next = pos;
        tmp->_Pre = pos->_Pre;
        pos->_Pre->_Next = tmp;
        pos->_Pre = tmp;
    }

    void Erase(Node<T>* pos)
    {
        assert(pos);

        pos->_Pre->_Next = pos->_Next;
        pos->_Next->_Pre = pos->_Pre;
        delete[] pos;
    }

    void Clear()
    {
        while(_pHead->_Next != _pHead)
        {
            PopFront();
        }
    }

    void Assign(size_t n, const T& data)
    {
        Node<T>* tmp = _pHead->_Next;
        while(n--)
        {
            if(tmp != _pHead)
            {
                tmp->_data = data;
                tmp = tmp->_Next;
            }
            else
            {
                PushBack(data);
            }
        }
    }

    bool Empty()const
    {
        return _pHead->_Next == _pHead;
    }

    size_t Size()const
    {
        size_t size = 0;
        Node<T>* tmp = _pHead->_Next;
        while(tmp != _pHead)
        {
            size++;
            tmp = tmp->_Next;
        }
        return size;
    }

    void Print()
    {
        Node<T>* tmp = _pHead->_Next;
        while(tmp != _pHead)
        {
            cout<<tmp->_data<<"  ";
            tmp = tmp->_Next;
        }
        cout<<endl;
    }

private:
    Node<T>* CreatNode(const T& data)
    {
        return new Node<T>(data);
    }

private:
    Node<T>* _pHead;
};

int main()
{
    List<int> L;
    L.PushBack(1);
    L.PushBack(2);
    L.PushBack(3);
    L.PushBack(4);
    L.PushBack(5);
    L.Print();

    L.PopBack();
    L.Print();

    L.PushFront(10);
    L.Print();

    L.PopFront();
    L.Print();

    Node<int>* tmp = L.Find(4);
    L.Insert(tmp, 4);
    L.Print();

    L.Erase(tmp);
    L.Print();

    cout<<L.Empty()<<endl;
    L.Clear();
    cout<<"Size = "<<L.Size()<<endl;

    L.Assign(10, 5);
    L.Print();

    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值