此文章为上一篇文章续篇
面向对象三大特性:封装、继承、多态。这也是面向对对象语言相对面向过程而言,最大的优势和特点。面向对象使得程序更加利于维护,让设计人员更加关注设计,要想真正的理解面向对象的特性,则必须要清楚和掌握这三大规律。
链式结构分析
对于链式结构而言,与线性结构有所差别的是,其逻辑结构不为连续的,而是采用一种前驱后继的方式进行节点之间的关联,使得上一个节点,可以访问到下一个节点,从而形成一种链式的线性结构。链式结构的优点在于,其插入删除的效率较高,因此叫常用于插入删除较频繁的情形。
对于链式结构,应该有的属性为:
- 链表由节点构成,每一个节点包含一个数据
- 链表为链式结构,在物理上不连续
- 链式结构为随机存储结构,在堆区开辟空间,需要手动管理内存
内存管理请参看:C++内存管理和智能指针
开始链表的实现
- 链表节点的实现
/**
* 链表节点类
*/
template<class T>
class ZLinkedListNode {
public:
/**
* 默认构造函数,需要目的类型提供默认构造函数å
*/
ZLinkedListNode<T>(){_nextNode = nullptr;}
/**
* 构造函数,用于构造一个链表节点,并为其制定一个节点值
* @param data 要赋予的节点的值
*/
ZLinkedListNode<T>(const T &data);
/**
* 构建指定前驱的链表节点
* @param data 要指定节点的值
* @param preNode 要指定的上一个节点
*/
ZLinkedListNode<T>(const T &data, ZLinkedListNode &preNode);
/**
* 获取节点值
* @return 返回该节点值的副本,为保证安全,应该相应的数据类型重载赋值和拷贝构造
*/
const T data() const{
return _data;}
/**
* 引用该节点的值
* @return 返回节点值的引用
*/
T &ref() {
return _data;}
/**
* 获取下一个节点
* @return 返回下一个节点
*/
ZLinkedListNode<T> *nextNode(){
return _nextNode;}
/**
* 下一个节点的引用
* @return 返回下一个节点指针的引用
*/
ZLinkedListNode<T> *&nextNodeRef(){
return _nextNode;}
/**
* 设置下一个节点
* @param nextNode 要设置的下一个节点
*/
void setNextNode(ZLinkedListNode<T> *nextNode);
protected:
T _data;// 节点数据
ZLinkedListNode<T> *_nextNode; // 下一个节点
};
/*以下为Node的实现*/
template<class T>
ZLinkedListNode<T>::ZLinkedListNode(const T &data) {
_data = data;
_nextNode = nullptr;
}
template<class T>
ZLinkedListNode<T>::ZLinkedListNode(const T &data, ZLinkedListNode &preNode) {
_data = data;
// 连接节点
preNode._nextNode = this;
_nextNode = nullptr;
}
template<class T>
void ZLinkedListNode<T>::setNextNode(ZLinkedListNode<T> *nextNode) {
_nextNode = nextNode;
}
- 链表的实现
/**
* 链表类
*/
template<class T>
class ZLinkedList : public Sequence<T> {
public:
/**
* 默认构造函数,为节省空间,不设置哨兵节点
*/
ZLinkedList<T>();
/**
* 根据指定值创建链表,该值为链表头部
* @param data 要指定的头部值
*/
ZLinkedList<T>(const T& data);
/**
* 创建指定值的指定个数的链表
* @param data 指定值
* @param count 指定值的个数
*/
ZLinkedList<T>(const T& data, z_size count);
/**
* 插入到最后一个位置
*/
virtual void push_back(const T& val);
/**
* 从指定位置中,移除元素,并返回该元素的副本,若为指针,请自行进行内存管理
* @param pos 元素位置
* @return 返回该元素值
*/
virtual T pop(const rank pos);
/**
* 访问指定位置的值
* @param pos 元素所在的位置
* @return 返回该位置的元素值
*/
virtual const T &at(const rank pos) const;
/**
* 移除指定位置元素
* @param pos 元素所在位置
* @return 返回是否移除成功
*/
virtual bool remove(const rank pos);
/**
* 获取迭代器
* @return 返回迭代器
*/
virtual Iterator<T> &iterator();
/**
* 重载访问器
* @param pos 元素位置
* @return 返回元素引用
*/
virtual T& operator[](const rank pos);
/**
* 判断是否为空表
*/
bool isEmpty() const;
virtual ~ZLinkedList();
z_size length() const{
return _length;}
//声明友元关系
friend class ZLinkedListIterator<T>;
protected:
ZLinkedListNode<T> *_list_head; // 链表头结点
ZLinkedListNode<T> *_list_tail; // 链表尾节点,冗余数据,为了加快尾插法的效率
z_size _length; // 长度
Iterator<T> *preIterator; // 上一个迭代器,用于迭代器的释放
};
/*
链表的实现
*/
template<class T>
ZTemplate::ZLinkedList<T>::ZLinkedList():Sequence<T>() {
_list_head = nullptr;
_length = 0;
_list_tail = nullptr;
preIterator = nullptr;
}
template<class T>
ZTemplate::ZLinkedList<T>::ZLinkedList(const T &data):Sequence<T>() {
_list_