类的封装性 -- 双向链表

  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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值