类的封装性 -- 双向链表

来源:互联网 发布:java主流技术 编辑:程序博客网 时间:2024/06/05 08:17
  1. 双向链表的节点
struct Node {     Node(const DataType& data)         : _pNext(NULL)         , _pPre(NULL)         , _data(data)     {}     Node* _pNext; //指向下一个节点    Node* _pPre; //指向上一个节点    DataType _data; //数据}; 
  1. 链表类的建立:
class List { public:     //链表的操作函数private:     Node* BuyNode(const DataType& data)     {         return new Node(data);     } private:     Node* _pHead; //头指针}; 
  1. 操作函数:
#include"ListNode.h"List::List(size_t n, DataType data) //构造{    if(n<=0)        _pHead = NULL;    else if(n == 1)    {        _pHead = BuyNode(data);    }    else    {        _pHead = BuyNode(data);        Node* pri = _pHead;        while(--n)        {            pri->_pNext = BuyNode(data);            pri->_pNext->_pPre = pri;            pri = pri->_pNext;        }    }}List::List(const List& l) //拷贝构造ps:不能是浅拷贝{    if(l._pHead == NULL)        _pHead = NULL;    else    {        Node *pri = l._pHead;        _pHead = BuyNode(pri->_data);//先创建头节点        while(pri->_pNext != NULL)        {            pri = pri->_pNext;            PushBack(pri->_data);//在逐步用尾插的方法复制链表l        }    }}List::~List()//析构函数{    Node *pri = _pHead;    if(_pHead == NULL)        return;    while(pri->_pNext!=NULL)    {        pri = pri->_pNext;    }//找到最后一个节点的指针    Node *avi = NULL;//    while(pri != NULL)//倒着便利    {        avi = pri->_pPre;//先记住记住前一个节点的指针        delete pri;//释放当前指针        pri = avi;    }    _pHead = NULL;}List& List::operator=(const List& l) //赋值运算符的重载{    List tmp(l);    swap(tmp._pHead,_pHead);//处理方法与string类重载方法一样    return *this;}void List::Print() //打印链表{    Node *pri = _pHead;    while(pri)//便利打印    {        cout<<pri->_data<<"->";        pri = pri->_pNext;    }    cout<<"end"<<endl;}void List::PushBack(const DataType& data)//尾插{    if(_pHead == NULL)    {        _pHead = BuyNode(data);    }    else    {        Node *pri = _pHead;        while(pri->_pNext != NULL)            pri = pri->_pNext;//找到最后一个节点的指针        pri->_pNext = BuyNode(data);//插入节点        pri->_pNext->_pPre = pri;    }}void List::PopBack()//尾删{    if(_pHead == NULL)        return;    else if((_pHead->_pNext == NULL))    {        delete _pHead;        _pHead = NULL;    }    else    {        Node *pri = _pHead;        while(pri->_pNext != NULL)            pri = pri->_pNext;//找到最后一个节点指针        pri = pri->_pPre;//返回去找到倒数第二的节点指针        delete pri->_pNext;//释放最后一个节点的空间        pri->_pNext = NULL;//并置为空    }}void List::PushFront(const DataType& data)//头插{    Node *pri = BuyNode(data);    if(_pHead == NULL)    {        _pHead = pri;    }    else    {        pri->_pNext = _pHead;        _pHead = pri;        _pHead->_pNext->_pPre = _pHead;    }}void List::PopFront()//头删{    if(_pHead==NULL)//空链表        return;    else if(_pHead->_pNext == NULL)    {        delete _pHead;//只有一个节点        _pHead = NULL;    }    else    {        Node *pri = _pHead;//先记住第一个节点的指针        _pHead = _pHead->_pNext;        _pHead->_pPre = NULL;        delete pri;//再去掉头一个几点之后,释放空间    }}Node* List::Find(const DataType& data)//查找{    Node *pri = _pHead;    while(pri != NULL)//遍历    {        if(pri->_data == data)            return pri;        pri = pri->_pNext;    }    return NULL;}void List::Insert(Node* pos, const DataType& data)//插入{    assert(pos);//节点为空,就不能往下进行    if(pos == _pHead)//头插        PushFront(data);    else    {        Node *pri = BuyNode(data);        //注意这里的连接顺序,先让新节点连到pos和上一个节点之间,再断开pos与上一个节点        pri->_pNext = pos;//先让新节点的下一个指针指向pos        pri->_pPre = pos->_pPre;//再新节点的上一个指针指向pos的上一个指针所指的位置        pos->_pPre->_pNext = pri;//让pos的上个节点指针为新节点的指针        pos->_pPre = pri;//    }}void List::Erase(Node* pos)//删除{    assert(pos);//节点为空,就不能往下进行    if(pos == _pHead)//头删        PopFront();    else if(pos->_pNext == NULL)//这里存在问题,若pos不在该链表中??        PopBack();    else    {        //Node *pri = pos;        pos->_pNext->_pPre = pos->_pPre;//        pos->_pPre ->_pNext= pos->_pNext;        delete pos;//删除操作不会改变pos的值,所以直接delete pos    }}size_t List::Size()//大小{    int count = 0;    Node *pri = _pHead;    while(pri != NULL)    {        ++count;        pri = pri->_pNext;    }    return count;}bool List::Empty()const//检测是否为空,若为空返回false 错误返回false 0{    return !_pHead; }