本文共 27089 字,大约阅读时间需要 90 分钟。
方式一
方式二
方式三
异常类实现(illegalParameterValue)
class illegalParameterValue { private: string message; public: illegalParameterValue() : message( "Illegal Parameter Value") {} illegalParameterValue( const char* s) :message(s) {} const char *what() { return message.c_str(); } };
template< typename T> void changeLength(T* &a, int oldLength, int newLength) { if (newLength < 0) { throw illegalParameterValue( "new length must be >=0"); } T *arr = new T[newLength]; int length = min(oldLength, newLength); copy(a, a + length, arr); delete [] a; a = arr; }
线性表类实现
template< typename T> class linearList { public: virtual ~linearList() {}; //当线性表为空时返回true virtual bool empty() const = 0; //返回线性表的元素个数 virtual int size() const = 0; //返回索引theIndex的元素 virtual T& get(int theIndex)const = 0; //返回元素theElement第一次出现时的索引 virtual int indexOf(const T& theElement) const = 0; //删除索引为theIndex的元素 virtual void earse(int theIndex) = 0; //把theElement插入线性表中索引为theIndex的位置上 virtual void insert(int theIndex, const T& theElement) = 0; //把线性表插入输出流out virtual void output(ostream& out)const = 0; }; template< typename T> class arrayList : public linearList{ public: arrayList( int initialCapacity = 10); //构造函数 arrayList( const arrayList & other); //拷贝构造 ~arrayList(); //析构函数 bool empty()const override; int size()const override; T& get(int theIndex)const override; int indexOf(const T& theElement)const override; void earse(int theIndex)override; void insert(int theIndex, const T& theElement)override; void output(ostream& out)const override; //返回数组的容量 int capacity()const; protected: T *element; //存储线性表的一维数组 int arrayLength; //一位数组的容量 int listSize; //当前线性表的元素个数 protected: void checkIndex(int theIndex)const; //检查索引theIndex是否有效 };
构造函数
template< typename T> arrayList::arrayList( int initialCapacity) { if (initialCapacity < 1) { ostringstream s; s << "Initial capacity is " << initialCapacity << ",Must be >0"; throw illegalParameterValue(s.str().c_str()); //str()将ostringstream转换为string,c_str()将string转换为const char* } arrayLength = initialCapacity; element = new T[arrayLength]; listSize = 0; }
template< typename T> arrayList::arrayList( const arrayList & other) { arrayLength = other.arrayLength; listSize = other.listSize; element = new T[arrayLength]; copy(other.element, other.element + listSize, element); }
template< typename T> arrayList::~arrayList() { delete[] element; }
empty、size、capacity
template< typename T> bool arrayList::empty() const { return listSize == 0; } template< typename T> int arrayList ::size() const { return listSize; } template< typename T> int arrayList ::capacity() const { return arrayLength; }
检索下标合格性(checkIndex)
template< typename T> void arrayList::checkIndex( int theIndex) const { if ((theIndex< 0) || (theIndex>=arrayLength)) { ostringstream s; s << "index=" << theIndex << ",size=" << arrayLength; throw illegalParameterValue(s.str().c_str()); } }
template< typename T> T& arrayList::get( int theIndex) const { checkIndex(theIndex); return element[theIndex]; }
template< typename T> int arrayList::indexOf( const T& theElement) const { int index; //find成功返回查找的迭代器位置,失败返回参数2 index = ( int)(find(element, element + listSize, theElement) - element); //如果没有找到 if (index == listSize) { return - 1; } else return index; }
删除指定索引处的元素(earse)
template< typename T> void arrayList::earse( int theIndex) { checkIndex(theIndex); //参数12分别为要移动的区间的起始迭代位置和尾后迭代器 copy(element+ theIndex+ 1, element+ listSize, element + theIndex); element[--listSize].~T(); }
在指定索引处插入元素(insert)
template< typename T> void arrayList::insert( int theIndex, const T& theElement) { if ((theIndex< 0) || (theIndex>listSize)) { ostringstream s; s << "index=" << theIndex << ",size=" << arrayLength; throw illegalParameterValue(s.str().c_str()); } if (listSize == arrayLength) { changeLength(element, arrayLength, arrayLength * 2); arrayLength *= 2; } //会复制前两个迭代器参数指定的序列。第三个参数是目的序列的结束迭代器 copy_backward(element+ theIndex, element+ listSize, element + listSize+ 1); element[theIndex] = theElement; listSize++; }
打印线性表元素(output)
template< typename T> void arrayList::output(ostream& out) const { copy(element, element+ listSize,ostream_iterator (out, " ")); }
template< typename T> ostream& operator<<(ostream& out, const arrayList& x) { x.output(out); return out; }
改写earse函数
template< typename T> void arrayList::earse( int theIndex) { checkIndex(theIndex); copy(element+ theIndex+ 1, element+ listSize, element + theIndex); if (listSize < (arrayLength / 4)) { changeLength(element, arrayLength, arrayLength / 2); } element[--listSize].~T(); }
演示效果
int main() { linearList< int>* list = (linearList< int>*) new arrayList< int>(); cout << "Current size:"<< list->size()<< "\n"<< endl; cout << "Current list is:"; list->output( cout); list->insert( 0, 1); list->insert( 0, 2); cout << "Current size:" << list->size() << "\n" << endl; cout << "Current list is:"; list->output( cout); cout << "The index of 2 is:" << list->indexOf( 2)<< "\n"<< endl; list->earse( 1); cout << "Current list is:"; list->output( cout); return 0; }
template< typename T> class arrayList : public linearList{ /*...*/ public: class iterator; iterator begin() { return iterator(element); } iterator end() { return iterator(element + listSize); } class iterator { public: typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; public: iterator(T* thePosition = 0) { position = thePosition; } /*~iterator() { //析构函数出错,不知道为什么,待续 if (position) { delete[] position; position = nullptr; } }*/ T& operator*() const { return *position; } T* operator->() const { return &*position; } iterator& operator++() { ++position; return * this; } iterator operator++( int) { iterator old = * this; ++position; return old; } iterator& operator--() { --position; return * this; } iterator operator--( int) { iterator old = * this; --position; return old; } bool operator==( const iterator other) const { return position == other.position; } bool operator!=( const iterator other) const { return position != other.position; } protected: T *position; }; /*...*/ };
演示案例
int main() { arrayList< int> list; list.insert( 0, 1); list.insert( 1, 2); list.insert( 2, 3); list.insert( 3, 4); arrayList< int>::iterator iter; for (iter = list.begin(); iter != list.end(); ++iter) { cout <<*iter << " "; } cout << "\n" << endl; return 0; }