模板实现顺序表+双向链表

用模板写链表主要还是为了实现代码的类型通用性,用模板写函数或类都与是类型无关的,因此,STL中都是用模板来实现容器,下面我们来介绍用模板实现顺序表和带头结点的双向循环链表。 以下代码将实现顺序表和链表的增、删、查、改、判空等常用接口以做练习。

顺序表


#pragma once

template<class T>
class SeqList
{
public:
    SeqList()
        :_a(NULL)
        , _size(0)
        , _capacity(0)
    {};

    SeqList(const SeqList<T>&s)//构造
    {
        _a = new T[s.size];
        for (size_t i = 0; i < s.size; ++i){
            _a[i] = s._a[i];
        }
        _size = s.size;
        _capacity = s.size;
    }

    SeqList<T>& operator = (SeqList<T> S) {//赋值运算符重载
        swap(_a, s._a);
        swap(_size, s._size);
        swap(capacity, s._capacity);

        return *this; 
    }
//析构
    ~SeqList(){
        if (_a){
            delete[] _a;
        }
    }

    void PushBack(const T& x)
    {
        CheckCapacity();
        _a[_size++] = x;//operatpr = 
    }

    void PopBack() {
        assert(_size > 0);
        --_size;
    }


    size_t GetSize() {
        return _size;
    }

    bool IsEmpty()
    {
        return _size == 0;
    }

    T& GetBackElement()
    {
        assert(_size > 0);
        return _a[size - 1];
    }

    //void Insert(size_t pos, const T& x);
    //void Erase(size_t pos);
    //size_t find(const T& x);


    void CheckCapacity()
    {
        if (_size == _capacity)
        {
            size_t newSize = _capacity ? _capacity * 2 : 3;//如果_capacity存在扩容2倍,置容量为3.
            T* tmp = new T[newSize];//临时新顺序表

            for (size_t i = 0; i < _size; ++i)//逐个拷贝至临时tmp中暂时存放
            {
                tmp[i] = _a[i];
            }

            delete[] _a;//释放回收旧表
            _a = tmp;//将tmp存放节点们赋给
            _capacity = newSize;
            assert(_a);//确保拷贝成功 _a不为空
        }   
    }

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

带头结点的循环双向链表

#pragma once

template<typename T>
struct ListNode
{
    ListNode<T>* _next;
    ListNode<T>* _prev;
    T _data;

    ListNode(const T& x)
        :_next(NULL)
        ,_prev(NULL)
        ,_data(x)
    {}
};

// 带头结点的双向循环链表
template<class T>
class List
{
    typedef ListNode<T> Node; 
public:
    List()
    {
        _head = new Node(T());
        _head->_next = _head;
        _head->_prev = _head;
    }

    // l2(l1)
    List(const List<T>& l)
    {
        _head = new Node(T());
        _head->_next = _head;
        _head->_prev = _head;

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

    List<T>& operator=(List<T> l)
    {
        swap(_head, l._head);
        return *this;
    }

    ~List()
    {
        Clear();
        delete _head;
        _head = NULL;
    }

    void Clear()
    {
         Node* cur = _head->_next;
         while (cur != _head)
         {
            /* Node* next = cur->_next;
             delete cur;
             cur = next;*/
             Node* del = cur;
             cur = cur->_next;
             delete del;
         }

         _head->_next = _head;
         _head->_prev = _head;
    }

    void PushBack(const T& x)
    {
        Insert(_head, x);
    }

    void PopBack()
    {
        Erase(_head->_prev);
    }

    void PopFront()
    {
        Erase(_head->_next);
    }

    void PushFront(const T& x)
    {
        Insert(_head->_next, x);
    }

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

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

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

    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 Print()
    {
        Node* cur = _head->_next;
        while (cur != _head)
        {
            cout<<cur->_data<<" ";
            cur = cur->_next;
        }
        cout<<endl;
    }

    T& Back()
    {
        assert(!Empty());

        return _head->_prev->_data; 
    }

    const T& Front()
    {
        assert(!Empty());

        return _head->_next->_data; 
    }

    inline bool Empty()
    {
        return _head->_next == _head;
    }

    size_t Size()
    {
        size_t size = 0;
        Node* cur = _head->_next;
        while (cur != _head)
        {
            ++size;
            cur = cur->_next;
        }

        return size;
    }

protected:
    Node* _head;
};

//void TestList1()
//{
//  List<int> l;
//  l.PushBack(1);
//  l.PushBack(2);
//  l.PushBack(3);
//  l.PushBack(4);
//
//  l.PopBack();
//  l.PopBack();
//  l.PopBack();
//  l.PopBack();
//  l.Print();
//}

void TestList2()
{
    List<int> l;
    l.PushBack(1);
    l.PushBack(2);
    l.PushBack(3);
    l.PushBack(4);

    List<int> l2(l);
    l2.Print();
}

测试顺序表,链表

#include<iostream>
#include<string>
#include<assert.h>
#include<windows.h>
#include "SeqList.h"
#include "List.h"
using namespace std;

void TestSeqList()
{
    //SeqList<int> s1;
    //s1.PushBack(1);
    //s1.PushBack(2);
    //s1.PushBack(3);
    //s1.PushBack(4);
    //s1.PushBack(5);
    //s1.print();

    SeqList<string>s2;
    s2.PushBack("Still");
    s2.PushBack("Still is pig!!");
    s2.PushBack("What a foolish Still!");
    s2.PushBack("Stillis a pig forever!");

    s2.print();
    //SeqList<string> s3(s2);
    //s3.print();
}

int main()
{
    TestSeqList();
    //TestList2();
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ego_bai/article/details/79633556
今日推荐