C++模板及用模板实现双向循环链表,顺序表

本文探讨了泛型编程的概念,强调模板在其中的重要作用。内容包括模板函数和模板类的介绍,以及如何利用C++模板实现一个有头结点的双向循环链表,讲解链表的分类,并提供了顺序表的相关知识。

模板是泛型编程的基础。
所谓泛型编程就是编写与类型⽆关的逻辑代码,是⼀种复⽤的⽅式。
模板分为模板函数和模板类。

函数模板格式:
template <class 形参名1, class 形参名2, class 形参名n>
返回类型 函数名(参数列表)
{
    ...
}
模板形参的定义既可以使⽤class,也可以使⽤typename,含义是相同的。

但是公司的

注:模板未实例化时,代码内部的语法错误检测不到。

双向循环链表

链表分为有头结点和无头结点,单向和双向,循环和不循环
这里实现一个有头结点的双向循环链表
发生的

#include<iostream>
#include<windows.h>
#include<assert.h>
using namespace std;
template<class T>
struct ListNode
{
    T _data;
    ListNode<T>* _next;
    ListNode<T>* _prev;

    ListNode(const T& x=T())
        :_data(x)
        , _next(NULL)
        , _prev(NULL)
    {}
};
template<class T>
class List
{
    typedef ListNode<T> Node;
public:
    List()
    {
        _head = new Node;
        _head->_prev = _head;
        _head->_next = _head;
    }

    //传统写法
    List(const List<T> &l)
    {
        _head = new Node(T());
        _head->_next = _head;
        _head->_prev = _head;

        Node*cur = l._head->_next;
        while (cur != l._head)
        {
            PushBack(cur->_data);
            cur = cur->_next;
        }
    }


    //现代写法
    List<T>&operator=(List<T> l)
    {
        swap(_head, l._head);

        return *this;

    }

    ~List()
    {
        Clear();
        delete _head;

    }
    void Clear()//不清除头结点
    {
        Node*cur = _head->_next;
        while (cur != _head)
        {
            Node*del = cur;
            cur = cur->_next;
            delete del;
        }
        _head->_next = _head;
        _head->_prev = _head;
    }

    //增删查改
    void PushBack(const T&x)
    {
        //Node*tail = _head->_prev;//找到尾结点
        //Node*tmp = new Node(x);//创建新节点


        //_head->_prev = tmp;
        //tmp->_next = _head;

        //tail->_next = tmp;
        //tmp->_prev = tail;
        Insert(_head, x);
    }
    void PopBack()
    {
        //assert(_head->_next != _head);//断言
        //Node*tail = _head->_prev;//找到尾结点
        //Node*prev = tail->_prev;//找到尾结点的前一个结点
        //delete tail;//删除尾结点

        //_head->_prev = prev;//头结点的前一个结点为prev
        //prev->_next = _head;//prev的后一个结点为_head
        Erase(_head->_prev);
    }
    void PopFront()
    {
        //assert(_head->_next != _head);
        //Node*tmp = _head->_next;
        //Node*next = tmp->_next;
        //delete tmp;
        //
        //_head->_next = next;
        //next->_prev = _head;

        Erase(_head->_next);


    }
    void PushFront(const T&x)
    {
        //Node*tmp = new Node(x);
        //Node*next = _head->_next;

        //_head->_next = tmp;
        //tmp->_prev = _head;

        //tmp->_next = next;
        //next->_prev = tmp;
        Insert(_head->_next, x);
    }
    bool Empty()//判断是否为空
    {
        return _head->_next == _head;
    }

    void Print()
    {
        Node*cur = _head->_next;
        while (cur!= _head)
        {
            cout << cur->_data << "";
            cur = cur->_next;
        }
        cout << endl;
    }
    void Erase(Node*pos)
    {
        assert(pos&&pos != _head);
        Node* prev = pos->_prev;
        Node* next = pos->_next;
        delete pos;

        prev->_next = next;
        next->_prev = prev;

    }
    void Insert(Node*pos, const T&x)
    {
        assert(pos);

        Node*tmp = new Node(x);
        Node*prev = pos->_prev;


        prev->_next = tmp;
        tmp->_prev = prev;

        tmp->_next = pos;
        pos->_prev = tmp;
    }

    Node* Find(const T &x)
    {
        Node*cur = _head->_next;
        while (cur!=_head)
        {
            if (cur->_data == x)
            {
                return cur;
            }
            cur = cur->_next;
        }
        return NULL;
    }
protected:
    Node* _head;
};

顺序表


template<class T>
class Seqlist
{
public:
    Seqlist()
        :_a(NULL)
        , _capacity(0)
        , _size(0)
    {}
    Seqlist(Seqlist & s)
        :_a(s._a)
        , _capacity(s._capacity)
        , _size(s._size)
    {}
    Seqlist& operator=(Seqlist&s)
    {
        swap(_a, s._a);
        swap(_capacity, s._capacity);
        swap(_size, s.size);
        return *this;
    }

    void CheakCapacity()
    {
        if (_size == _capacity)
        {
            size_t Newsize = _size ? _capacity * 2 : 3;
            _a = (T*)realloc(_a, Newsize*sizeof(T));
            _capacity = Newsize;
        }
    }
    void PushBack(const T &x)
    {
        CheakCapacity();
        _a[_size++] = x;
    }
    void PopBack()
    {
        assert(_size);
        --_size;

    }
    void PushFront(const T &x)
    {
        CheakCapacity();
        int end = _size;
        while (end>0)
        {
            _a[end] = _a[end - 1];
            end--;
        }
        _a[0] = x;
        ++_size;
    }
    void PopFront()
    {
        assert(_a);
        int n = 0;
        while (n<_size-1)
        {
            _a[n] = _a[n + 1];
            n++;
        }
        --_size;
    }
    ~SeqList()
    {
        if (_a)
        {
            free(_a);

        }
    }
    void Print()
    {
        for (size_t i = 0; i < _size; i++)
        {
            cout << _a[i] << " ";
        }
        cout << endl;
    }
private:
    T *_a;
    size_t _capacity;
    size_t _size;

};
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值