模拟实现 list

链表前面我已经写过了,不过写的是单链表,而C++库中的list是双链表,那么,我们就来模拟实现一下双链表,这样对于库中的list也会有更加深刻的了解。

那么首先我们先来了解一下双链表的结构,双链表无非就是比单链表多了一条链,单链表只有一条指向下一个节点的链,而双链表会多一条指向前一个节点的链。说白了就是多了一个指针罢了。

而具体的函数功能还是那些,那么我们就来实现这个链表吧!

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

#pragma once

typedef int DataType;

struct Node         //节点
{
    Node(const DataType& data)
    : _data(data)
    , _pNext(NULL)
    , _pPre(NULL)
    {}

    DataType _data;         //值
    Node* _pNext;           //下一个节点
    Node* _pPre;             //上一个节点
};

class List
{
public:
    List()
        : _pHead(NULL)
        , _pTail(NULL)
        , _size(0)
    {}

    List(size_t n, const DataType& data = DataType())
    {}

    List(const List& l)
    {
        // _CopyList(l._pHead);
    }

    List& operator=(const List& l)
    {
        if (this != &l)
        {
            //_DestroyList();
            //_CopyList(l._pHead);
        }

        return *this;
    }

    ~List()
    {
        _DestroyList();
    }

    //尾插
    void PushBack(const DataType& data)
    {
        Node* pNode = new Node(data);   //构造一个新的节点
        if (NULL == _pHead)
        {
            _pHead = _pTail = pNode;   
        }
        else
        {
            _pTail->_pNext = pNode;  //先将新节点连接到尾部
            pNode->_pPre = _pTail;    
            _pTail = _pTail->_pNext;    //将尾节点向后移一位
        }

        ++_size;
    }

    //尾删
    void PopBack()
    {
        if (NULL == _pHead)
        {
            assert(false);
            return;
        }
        else if (_pHead == _pTail)//如果只有一个节点,删除头节点,将两个指针都置空
        {
            delete _pHead;
            _pHead = _pTail = NULL;
        }
        else          
        {
            _pTail = _pTail->_pPre;//先将尾节点向前移一位
            delete _pTail->_pNext;//再将尾节点后面的节点空间释放
            _pTail->_pNext = NULL;//最后指针置空
        }

        --_size;
    }

    //头插
    void PushFront(const DataType& data)
    {
        Node* pNode = new Node(data);
        if (NULL == _pHead)
        {
            _pHead = _pTail = pNode;
        }
        else
        {
            pNode->_pNext = _pHead;
            _pHead->_pPre = pNode;
            _pHead = pNode;
        }

        ++_size;
    }

    //头删
    void PopFront()
    {
        if (NULL == _pHead)
        {
            assert(false);
            return;
        }
        else if (_pHead == _pTail)
        {
            delete _pHead;
            _pHead = NULL;
            _pTail = NULL;
        }
        else
        {
            _pHead = _pHead->_pNext;
            delete _pHead->_pPre;
            _pHead->_pPre = NULL;
        }

        --_size;
    }

    //插入函数
    void Insert(Node* pos, const DataType& data)
    {
        if (NULL == pos || NULL == _pHead)
            return;

        if (pos == _pTail)
        {
            PushBack(data);
        }
        else
        {
            Node* pNode = new Node(data);
            pNode->_pNext = pos->_pNext;//          1
            pos->_pNext->_pPre = pNode;
            pos->_pNext = pNode;//                         2
            pNode->_pPre = pos;
            ++_size;
        }
    }

    //删除
    void Erase(Node* pos)
    {
        if (NULL == pos || NULL == _pHead)
        {
            return;
        }
        else if (pos==_pHead)
        {
            PopFront();
        }
        else if (pos == _pTail)
        {
            PopBack();
        }
        else
        {
            pos->_pPre->_pNext = pos->_pNext;
            pos->_pNext->_pPre = pos->_pPre;
            delete pos;
            pos = NULL;
            --_size;
        }

    }

    void Assign(size_t n, const DataType data = DataType());

    void Clear()
    {
        _DestroyList();
        _size = 0;
    }

    void _DestroyList()
    {
            size_t size = _size;
            while (size)
            {
                PopFront();
                --size;
            }
    }

    void PrintList()
    {
        Node* pCur = _pHead;
        size_t size = _size;           //不要直接使用_size,否则会造成_size,变成很大的数
        while (size)
        {
            cout << pCur->_data <<" ";
            pCur = pCur->_pNext;
            --size;
        }
        cout << endl;
    }

    //access

    Node& Front()
    {
        return *_pHead;
    }

    const Node& Front()const
    {
        return *_pHead;
    }

    Node& Back()
    {
        return *_pTail;
    }

    const Node& Back()const
    {
        return *_pTail;
    }

    size_t Size()const
    {
        return _size;
    }

    bool Empty()const
    {
        return 0 == _size;
    }

private:
    Node* _pHead;
    Node* _pTail;
    size_t _size;
};

void FunTest()
{
    List l;
    l.PushBack(10);
    l.PushBack(20);
    l.PushBack(30);
    l.PushBack(40);
    l.PushBack(666);
    l.PrintList();

    l.PopBack();
    l.PrintList();

    l.PushFront(888);
    l.PrintList();

    l.PopFront();
    l.PrintList();

    cout <<(l.Back())._data<< endl;
    cout << (l.Front())._data << endl;
    cout << l.Size() << endl;

    l.Clear();
    l.PrintList();
}

int main()
{
    FunTest();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值