数据结构(一)

       数据结构是计算机专业的基础课。在学校的时候学了一遍觉得也没有什么(当然,老师说这是很重要的一门课程),在毕业设计中什么也没用上。工作快两年了,虽然还是什么也没用上,但渐渐的感觉数据结构越来越重要了。这种感觉是在潜移默化中形成的,于是重新找出课本开始温故而知新了。弹去书上的尘土随手翻看,猛然间看到了当初夹在书中的活页。上面记录着侯捷先生在《STL源码剖析》中的一段话:“作为一个程序员,如果你是做数据库编程的,大可以不懂汇编语言,如果你是写驱动程序的,大可以不必通晓人工智能,写编译器的可以不用懂什么计算机图形学,操作系统内核高手的不用精通网站架设。然而,如果你不懂数据结构与算法的基础知识,不具备数据结构与算法的基本技能,那就完全丧失成为一个程序员的资格!”。看到这,好像又回到在校时对中国软件业充满信心的那个时代。呵呵,快离校两年了,要不是见物生情在校时那种激情好像再也想不起来了。

       好了,说正题。在重新复习的过程中,我把书中例子再一次的实现,有的还进行了扩展。这里把他们拿出来,供大家参考。就像读书笔记一样,不过这里还加入了我个人的一些东西,望指正。(参考:《数据结构与算法------面向对象的C++设计模式》)

       C++中提供了内嵌的数组,但是有很多缺点。比如:不能把一个数组赋给另一个数组,对数组下标不进行越界检查,在编译期间一个数组的大小是静态和固定的,除非程序员使用动态内存分配。所以,我们先来写个数组类,完善这些功能。就像MFC中的CArray类一样,当然我们写的例子不可能像Microsoft封装的那样好,然而我们可以用简单的方法来实现复杂的功能。也许它看起来很低级,运行起来会很慢,但是它的的确确是我们自己改写的。下面是这个数组类的定义,包括成员函数。

template <class T>
class Array
{
 private:
       T *pData;
       unsigned int base;
       unsigned int length;
public:
       Array();
      Array(Array const&);
      Array(unsigned int ,unsigned int= 0);
      ~Array();
 
      T const &operator [] (int) const;
      T &operator [] (int);
      Array &operator = (Array const&);
      bool operator == (Array const&);

      bool IsEmpty() const;
      unsigned int GetBase() const;
      unsigned int GetLength() const;
      void SetLength(unsigned int,bool);
      void InsertAt(unsigned int nPos, T Value);
      void RemoveAt(unsigned int nPos);
};

        private域中有三个成员变量,成员pData是一个指向数组数据的指针,成员baselength用于计算数组下标。由于在C++内置的数组中下标是从0开始的,这是不可改变的。而base这个成员变量却可以帮助你修改这个规定。你可以随意设置这个变量的值,但是如果是负值或者比length大那么构造函数将按照默认值处理。

    这个类对[]===这三个操作符进行了重载。为的是能使这个类支持下标操作、赋值操作和比较操作。当然,可能存在好多bug,这还有待于进一步的修改。

#include <iostream>
using namespace std;
/*****************************************************************************
* Function Explain:默认构造函数
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline Array<T>::Array():pData(new T[0]),base(0),length(0)
{}
/*****************************************************************************
* Function Explain:重载构造函数,自由设定base和length
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template<class T>
inline Array<T>::Array(unsigned int unLength, unsigned int unBase)
{
 if((unLength < 0)||(unBase > unLength))
 {
  length = 0;
  base = 0;
  pData = new T[length];
 }
 else if(unBase < 0)
 {
  base = 0;
  length = unLength;
  pData = new T[length];
 }
 else
 {
  base = unBase;
  length = unLength;
  pData = new T[length];
 }
}
/*****************************************************************************
* Function Explain:拷贝构造函数
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template<class T>
inline Array<T>::Array(Array<T> const &array):pData(new T[array.length]),base(array.base),length(array.length)
{
 for(unsigned int i = 0;i < length; ++i)
 {
  data[i] = array.data[i];
 }
}
/*****************************************************************************
* Function Explain:析构函数
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline Array<T>::~Array()
{
 delete []pData;
}
/*****************************************************************************
* Function Explain:返回Index起始位置
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template<class T>
inline unsigned int Array<T>::GetBase() const
{
 return base;
}
/*****************************************************************************
* Function Explain:返回存储长度
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template<class T>
inline unsigned int Array<T>::GetLength() const
{
 return length;
}
/*****************************************************************************
* Function Explain: 重载操作符“=”,实现两个类对象的赋值操作
*                 
* Input Parameter:类对象
* Output Parameter:
* Return Values:
*****************************************************************************/
template<class T>
inline Array<T> &Array<T>::operator = (const Array<T> &array)
{
 Array<T> *&ptArray = const_cast<Array<T>*>(this);
 try
 {
        if(NULL == ptArray)
  {
   //throw std::domain_error("Initialize Pointer First!");
   ptArray = new Array<T>(array.GetLength(),array.GetBase());
  }
  else
  {
   ptArray->SetLength(array.GetLength(),false);
  }
  for(int i = array.GetBase(); i < array.GetLength();i++)
  {
   (*ptArray)[i] = array[i];
  }
 }
 catch(exception &e)
 {
  cerr << "Caught: " << e.what() << endl;
 }
 return *const_cast<Array<T>*>(this);
}
/*****************************************************************************
* Function Explain:重载操作符“==”,实现两个类对象的比较操作
*                 
* Input Parameter:类对象
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline bool Array<T>::operator == (Array const &array)
{
 if(this->GetLength() != array.GetLength())
 {
  return false;
 }
 Array<T> *&ptArray = const_cast<Array<T>*>(this);

 for(int i = array.GetBase(), int j = ptArray->GetBase();i < array.GetLength(),
                                                      j < ptArray->GetLength();i++,j++)
 {
  if(array[i] != (*ptArray)[j])
  {
   return false;
  }
 }
 return true;
}
/*****************************************************************************
* Function Explain:重载操作符“[ ]”,实现类对象的下标操作
*                 
* Input Parameter:Index位置
* Output Parameter:
* Return Values:
*****************************************************************************/

template<class T>
inline T const &Array<T>::operator [](int position) const
{
 int const offset = position - base;
 try
 {
     if((offset >= (int)length)||(offset < 0))
  {
   throw std::out_of_range("invalid position");
  }
 }
 catch(exception &e)
 {
  cerr << "Caught: " << e.what() << endl;
 }
 return data [offset];
}
/*****************************************************************************
* Function Explain:重载操作符“[ ]”,实现类对象的下标操作
*                 
* Input Parameter:Index位置
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline T &Array<T>::operator [](int position)
{
 int const offset = position - base;
 try
 { 
     if((offset >= (int)length)||(offset < 0))
  {
   throw std::out_of_range("invalid position");
  }
 }
 catch(exception &e)
 {
  cerr << "Caught: " << e.what() << endl;
 }
 return pData[offset];
}
/*****************************************************************************
* Function Explain:可以重新设定类对象的存储容量
*                 
* Input Parameter:类对象的新长度;是否要求元素移动标志
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline void Array<T>::SetLength(unsigned int newLength, bool bFlag)
{
 if(GetLength() == newLength)
 {
  return;
 }

 T *const newData = new T[newLength];
 if(bFlag)
  {
  unsigned int const min = length < newLength ? length : newLength;
    for(unsigned int i = 0; i < min; i++)
  {
   newData[i] = data[i];
  }
  }
  delete []data;
  data = newData;
  length = newLength;
}
/*****************************************************************************
* Function Explain:判断类对象是否是空
*                 
* Input Parameter:
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline bool Array<T>::IsEmpty() const
{
 if(0 == length)
 {
  return TURE;
 }
 else
 {
  return FALSE;
 }
}
/*****************************************************************************
* Function Explain:在类对象中插入一个元素
*                 
* Input Parameter:指定Index位置;插入值

* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline void Array<T>::InsertAt(unsigned int nPos, T Value)
{
 if(nPos > length)
 {
  return;
 }
    int nNewLength =  length + 1;
 T *const pNewData = new T[nNewLength];
 for(int i = 0; i < nPos - 1; i++)
 {
  pNewData[i] = data[i];
 }
 pNewData[nPos-1] = Value;
 if(nPos < length)
 { 
  for(i = nPos; i < length+1;i++)
  {
   pNewData[i] = data[i-1];
  }
 }
 delete []data;
 data = pNewData;
 length = nNewLength;
}
/*****************************************************************************
* Function Explain:在类对象中删除一个元素
*                 
* Input Parameter:指定Index位置
* Output Parameter:
* Return Values:
*****************************************************************************/
template <class T>
inline void Array<T>::RemoveAt(unsigned int nPos)
{
 if(nPos > length)
 {
  return;
 }
    int nNewLength =  length - 1;

 T *const pNewData = new T[nNewLength];
 for(int i = 0; i < nPos - 1; i++)
 {
  pNewData[i] = pData[i];
 }
 for(i = nPos-1; i+1 < length; i++)
 {
  pNewData[i] = pData[i+1];
 }
 
 delete []pData;
 pData = pNewData;
 length = nNewLength;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值