C++ 基础内容, 不值一提 Author:Jacky Wu 2006-5-5 引用该文章,必须注明其出处 http://blog.youkuaiyun.com/imwkj 链表是非常重要的一个基本的数据结构,一个健壮的链表是非常有用的,我在学习数据结构的时候实现了一个链表,并且实现它的叠带,由于常量叠带 const iterator操作与普通叠带是相似的,只是返回值的类型不同罢了,所以就没有写出相关的代码,不过,必须得清楚,const iterator也是非常重要的,否则对于常量对象就不能进行叠带操作了,代码中使用了异常,但并没有对异常进行处理,应该是要进行完备的异常安全处理的,只不过……,好了,这只是一个简陋的链表,不过要比一般教材上的强大多了,看代码: |
/* 显然,我们发现ChainNode 和 ChainIterator声明,实现方式并不是那么完美, 为了遵守数据的隐藏性规则,最好将这两个类声明为嵌套类 同时ChainIterator的实现方式将是标准化的,并不采用名称“ChainIterator” 而采用“iterator”这样,在声明一个迭代器的时候,就会象使用标准库那样 Chain<_T>::iterator iter = Chain<_T>.begin(); 同时我将重载迭代器的相关运算符,使其更象个真正的迭代器
所以,别被所做的小小的改动迷惑了,在关注算法的同时,提高自己的C++技能,未尝不是一件好事 enjoy!
如果关于迭代器有什么不清楚的,请参考《C++编成思想 第二版》p408 的内容 - “带有迭代器的PStash” 或者 《C++程序设计语言》 第19章有更详细的解释
在迭代器的实现中,将做更详细的讨论
JackyWu 1/6/2006 */
#ifndef CHAIN_H_ #define CHAIN_H_
#include <stdexcept> #include <cassert> #include <iostream>
template<class _T> class Chain { public: Chain() { first = 0; } virtual ~Chain(); inline bool IsEmpty() const { return 0 == first; } int Length() const; bool Find(int k, _T& x) const; int Search(const _T& x) const; Chain<_T>& Delete(int k, _T& x); Chain<_T>& Insert(int k, const _T& x); void Output(std::ostream& out) const;
//additional functions void Erase(); Chain<_T>& Append(const _T& x);
class iterator; //嵌套声明iterator迭代器类 friend class iterator; //友元
iterator begin() { return iterator(*this); } iterator end() { return iterator(*this, true); } //两个标准迭代函数
private:
class ChainNode; //声明ChainNode为私有类,
ChainNode *first; //第一节点指针 ChainNode *last; //最后节点 };
//***************************************************************** 定义ChainNode template<class _T> class Chain<_T>::ChainNode { friend class Chain; friend class iterator; private: _T data; ChainNode *link; }; //class ChainNode end //****************************************************************
//定义迭代器 Chain<_T>::iterator //迭代器的一些函数应当是内联的,但是这里为了代码的块清晰,牺牲这个功能 template<class _T> class Chain<_T>::iterator { public: iterator() : m_Lchain(0), m_pNode(0) {}; iterator(const Chain& ch); //用ch首节点初始化,对应begin() iterator(const Chain& ch, bool); //bool做标志,用ch最后一个节点初始化,对应end() iterator(const iterator& iter);
//重载迭代操作的相关运算符 iterator& operator++(); //++iterator iterator operator++(int); //iterator++ iterator& operator+=(int amount); bool operator==(const iterator& iter) const; bool operator!=(const iterator& iter) const; //对两个迭代器进行比较
_T& current() ; //返回当前迭代器节点的值p_Node->data; _T& operator*() ; //同上,但是操作为 *iterator _T* operator->() ; //同上
//iterator& operator--(); //--iterator //iterator operator--(int); //iterator-- //iterator& operator-=(int amount); /* * 显然,迭代器操作复杂性应当是常数的 O(1) * 那么,单向链表如果进行operator--() operator-=() 操作的话,就会产生效率问题(已经实现,请考察复杂性) * 当然,还有常量迭代器,等等,这里仅仅实现非常量的迭代器 * * 如果要实现所有的迭代操作,那就要使用标准库关于迭代器的定义, * 这样的复杂性显然不是我们所期望的,有兴趣的话可以去看一看STL关于<vector>定义 * 相关文件 * stl_iterator_base_funcs.h * stl_vector.h * GCC 4.0 */
private: const Chain &m_Lchain; ChainNode *m_pNode; };
template<class _T> Chain<_T>::iterator:: iterator(const Chain& ch) : m_Lchain(ch) { //注意引用数据成员的初始化方式 if (!ch.first) throw std::out_of_range("Out of Bounds"); //参数链表无内容 m_pNode = ch.first; }
template<class _T> Chain<_T>::iterator:: iterator(const Chain& ch, bool) : m_Lchain(ch) { if(!ch.first) throw std::out_of_range("Out of Bounds"); //同上参数链表无内容 m_pNode = ch.last->link; }
template<class _T> Chain<_T>::iterator:: iterator(const iterator& iter) : m_Lchain(iter.m_Lchain) { if (this != &iter) //防止自复制 { m_pNode = iter.m_pNode; //对同一链表进行操作,无须过多考虑内存镜像问题 //当然,如果iterator实现中有堆内存操作,另当别论 } }
template<class _T> typename Chain<_T>::iterator& //这里有点变化,只要只道这是嵌套类定义的返回类型就行了 Chain<_T>::iterator::operator++() { if (!m_Lchain.first) { throw std::out_of_range("Out of Bounds"); //链表无内容 } else if (!m_pNode) { throw std::out_of_range("Out of Bounds"); 超范围迭代 } else { m_pNode = m_pNode->link; } return *this; }
template<class _T> typename Chain<_T>::iterator Chain<_T>::iterator::operator++(int) { return operator++(); }
template<class _T> typename Chain<_T>::iterator& Chain<_T>::iterator::operator+=(int amount) { if (amount>=0) { if (amount>0) { if (!m_pNode) { throw std::out_of_range("Out of Bounds"); } } int step = 0; while (m_pNode && step<amount) { m_pNode = m_pNode->link; step++; }
if (!m_pNode && step<amount) throw std::out_of_range("Out of Bounds"); //迭代出界 } else { //amount<0 迭代反向操作,不支持 } return *this; }
/* 实现反向迭代 * 由于使用的是单向链表所以反向迭代的算法复杂度O(n),不合要求 * 这里提供其实现,但最好不要使用 * * iterator& operator--(); //--iterator iterator operator--(int); //iterator-- iterator& operator-=(int amount);
template<class _T> typename Chain<_T>::iterator& Chain<_T>::iterator::operator--() { if (!m_Lchain.first) throw std::out_of_range("Out of Bounds"); //在链头节点,不可以向前索引 if ( m_pNode == m_Lchain.first) throw std::out_of_range("Out of Bounds"); ChainNode *p = m_Lchain.first; while(p->link != m_pNode) { p = p->link; } m_pNode = p; return *this; }
template<class _T> typename Chain<_T>::iterator Chain<_T>::iterator::operator--(int) { return operator--(); }
template<class _T> typename Chain<_T>::iterator& Chain<_T>::iterator::operator-=(int amount) { if (amount>=0) { if (!m_Lchain.first) throw std::out_of_range("Out of Bounds");
int currentpos = 1; //当前迭代器所在链表中的位置,first: currentpos = 1 ChainNode *p = m_Lchain.first; while (p != m_pNode) { p = p->link; currentpos++; } int newpos = currentpos - amount; if (newpos <= 0) { throw std::out_of_range("Out of Bounds"); //超范围迭代 } else if (newpos == currentpos) { return *this; } else { p = m_Lchain.first; for (int i=1; i<newpos; i++) //注意偏移值范围 { p = p->link; } m_pNode = p; } } else { operator+=(-amount); //amount>0 反向迭代
} return *this; } *///OPERATOR--() Over
template<class _T> _T& Chain<_T>::iterator::current() { if (&m_Lchain) { return m_pNode->data; } else throw std::out_of_range("Out of Bounds"); }
template<class _T> _T& Chain<_T>::iterator::operator*() { return current(); }
template<class _T> _T* Chain<_T>::iterator::operator->() { return &(current()); }
template<class _T> bool Chain<_T>::iterator:: operator==(const iterator& iter) const { return (m_pNode == iter.m_pNode && &m_Lchain==&(iter.m_Lchain)); //这里可能需要对迭代器是否在同一个母链表进行判断 }
template<class _T> bool Chain<_T>::iterator:: operator!=(const iterator& iter) const { return (m_pNode != iter.m_pNode || &m_Lchain!=&(iter.m_Lchain)); } //iterator OVER //****************************************************************
template<class _T> Chain<_T>::~Chain() { ChainNode* next; while (first) { next = first->link; delete first; first = next; } }
template<class _T> int Chain<_T>::Length() const { ChainNode *current = first; int count = 0; while (current) { count++; current = current->link; } return count; }
template<class _T> bool Chain<_T>::Find(int k, _T& x) const { ChainNode *current = first; int index = 1; while (index<k && current) { current = current->link; index++; } if (current) { x = current->data; return true; } else return false; }
template<class _T> int Chain<_T>::Search(const _T& x) const { ChainNode *current = first; int index = 1; while (current && (current->data != x)) { index++; current = current->link; } if (current) { return index; } return -1; }
template<class _T> Chain<_T>& Chain<_T>::Delete(int k, _T& x) { if(k<1 || !first) throw std::out_of_range("Out of Bounds");
ChainNode *p = first; if (k==1) //欲删除头节点 { first = first->link; } else { ChainNode *q = first; for (int index=1; index<k-1 && q; index++) { q = q->link; } if (!q || !q->link) throw std::out_of_range("Out of Bounds");
p = q->link; if (p == last) //删除最后一个元素,重新设置last { last = q; } q->link = p->link; } x = p->data; delete p; p = 0; //删除此元素 return *this; }
template<class _T> Chain<_T>& Chain<_T>::Insert(int k, const _T& x) { if(k<0) throw std::out_of_range("Out of Bounds"); ChainNode *p = first; //索引指针p,p最终指向第k个节点 for (int index=1; index < k && p; index++) { p = p->link; } if (k>0 && !p) //无第K个元素, 注意此处,若(k==0 && !p) == true 指在新表头出插入节点 { //mmmm std::out_of_range("Out of Bounds"); }
ChainNode *newNode = new ChainNode; newNode->data = x; if (!k) //在头节点处插入 { if (!first) //第一次在头节点处插入,链表中无内容 { newNode->link = first; first = newNode; last = first; } else //链表中有内容 { newNode->link = first; first = newNode; } } else { newNode->link = p->link; p->link = newNode; if (p == last) //插入在最后 { last = newNode; } } return *this; }
template<class _T> void Chain<_T>::Output(std::ostream& out) const { ChainNode *current = first; while (current) { out << current->data << ", " ; current = current->link; } }
template<class _T> void Chain<_T>::Erase() { ChainNode *p; while(first) { p = first; first = first->link; delete p; } first = last = 0; //链表清空 }
template<class _T> Chain<_T>& Chain<_T>::Append(const _T& x) { ChainNode *y = new ChainNode; y->data = x; y->link = 0; if (first) { last->link = y; last = y; } else { first = last = y; } return *this; }
//全局重载operator<< template<class _T> std::ostream& operator<<(std::ostream& out, Chain<_T>& L) { L.Output(out); return out; }
#endif /*CHAIN_H_*/
|
实现了一个完整的chain 链表
最新推荐文章于 2022-05-12 13:16:00 发布