实现了一个完整的chain 链表

       C++ 基础内容, 不值一提

AuthorJacky Wu       2006-5-5

引用该文章,必须注明其出处              http://blog.csdn.net/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);

    /*

     * 显然,迭代器操作复杂性应当是常数的 O1

     * 那么,单向链表如果进行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_*/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值