类的封装性 -- 双向链表
来源:互联网 发布:java主流技术 编辑:程序博客网 时间:2024/06/05 08:17
- 双向链表的节点
struct Node { Node(const DataType& data) : _pNext(NULL) , _pPre(NULL) , _data(data) {} Node* _pNext; //指向下一个节点 Node* _pPre; //指向上一个节点 DataType _data; //数据};
- 链表类的建立:
class List { public: //链表的操作函数private: Node* BuyNode(const DataType& data) { return new Node(data); } private: Node* _pHead; //头指针};
- 操作函数:
#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
- 类的封装性 -- 双向链表
- 双向链表的两种实现与封装性
- 基于C++封装性的双向链表
- 数据结构4.进一步封装的双向链表
- 数据结构封装之《DLinkList双向链表》
- 数据结构封装之《DLinkList双向链表》
- 双向链表(c++封装)
- c++封装双向链表和顺序表
- C++方式封装顺序表、单链表和双向链表
- 基于模板类的双向链表
- 双向链表的排序
- 双向链表的查找
- 双向链表的建立
- 双向链表的实现
- 通用的双向链表
- 双向链表的实现
- 双向链表的实现
- 双向链表的建立
- 区间信息的维护与查询1(树状数组)
- 415. Add Strings
- jQuery 属性选择器
- 用MATLAB将RGB图像中的显示为相同颜色的像索点提取出来
- jsp内置对象及其方法
- 类的封装性 -- 双向链表
- 数据绑定
- 单点登录SSO的实现原理
- 简单的将驼峰命名变量转化为多个单词组成的变量名的方法
- Java NIO与反应器(reactor)模式
- jQuery 事件
- 研发寿康宝鉴一书力劝众生戒除邪淫
- grep工具的使用
- 排序<简单代码>