基于数组,实现一个简单的列表,支持如下功能:
- 下标
- 末尾添加,中间插入
- 末尾删除,中间删除
- 空间不够时自动扩容
- 清空所有元素
- 简单的错误检测
下面是代码:
#ifndef _ARRAYLIST_
#define _ARRAYLIST_
#include <iostream>
#include <stdexcept>
using namespace std;
template <typename T>
class ArrayList
{
public:
explicit ArrayList(int defaultCapacity = 10);
~ArrayList();
ArrayList( const ArrayList& rhs);
const ArrayList& operator= ( const ArrayList& rhs);
void Insert(int index,const T& value);
void Add(const T& value);
T Remove();
T Remove(int index);
T& operator[] ( int index) {
CheckRange(index);
return _values[index];
}
const T& operator[] ( int index) const {
CheckRange(index);
return _values[index];
}
int Size() const
{
return _size;
}
bool IsEmpty() const
{
return _size == 0;
}
void Print() const;
void Clear();
private:
void IncreaseCapacity();
void CheckRange(int index) const {
if( index < 0 || index >= _size )
throw out_of_range("Index is out of range");
}
int _size;
int _capacity;
T* _values;
};
template <typename T>
ArrayList<T>::ArrayList(int defaultCapacity)
: _size(0), _capacity(defaultCapacity)
{
_values = new T[defaultCapacity];
// assign default value of type T to all elements
for(int i=0;i<_capacity;++i)
_values[i] = T();
}
template <typename T>
ArrayList<T>::ArrayList( const ArrayList& rhs)
: _values(NULL)
{
operator=(rhs);
}
template <typename T>
const ArrayList<T>& ArrayList<T>::operator= ( const ArrayList<T>& rhs)
{
if ( this != &rhs )
{
delete [] _values;
_size = rhs._size;
_capacity = rhs._capacity;
_values = new T[_capacity];
// copy all elements from source list
// so we don't need to assign default value to spare elements
for(int i=0;i<_capacity;++i)
_values[i] = rhs._values[i];
}
return *this;
}
template <typename T>
ArrayList<T>::~ArrayList()
{
delete [] _values;
}
template <typename T>
void ArrayList<T>::Print() const
{
cout<< "Size=" << _size << endl;
cout<< "Capacity=" << _capacity << endl;
for(int i=0;i<_size;++i)
cout<< _values[i] << ",";
cout<<endl;
for(int i=0;i<_capacity;++i)
cout<< _values[i] << ",";
cout<<endl;
}
template <typename T>
void ArrayList<T>::Clear()
{
for(int i=0;i<_size;++i)
_values[i] = T();
_size = 0;
}
template <typename T>
void ArrayList<T>::IncreaseCapacity()
{
if(_size == _capacity)
{
T* newValues = new T[_capacity*2];
for(int i=0;i<_size;++i)
newValues[i] = _values[i];
// assign default value of type T to spare elements
for(int i=_capacity;i<_capacity*2;++i)
newValues[i] = T();
delete [] _values;
_values = newValues;
_capacity = _capacity*2;
}
}
template <typename T>
void ArrayList<T>::Add(const T& value)
{
IncreaseCapacity();
_values[_size++] = value;
}
template <typename T>
T ArrayList<T>::Remove()
{
if(IsEmpty())
{
throw logic_error("Can't remove element from empty list");
}
return _values[--_size];
}
template <typename T>
T ArrayList<T>::Remove(int index)
{
CheckRange(index);
T value = _values[index];
for( int i=index+1;i<_size;++i)
_values[i-1] = _values[i];
--_size;
// assign default value of type T to unused space
_values[_size]= T();
return value;
}
template <typename T>
void ArrayList<T>::Insert(int index,const T& value)
{
if( index >= 0 && index <= _size)
{
IncreaseCapacity();
for(int i=_size; i>index;--i)
_values[i] = _values[i-1];
_values[index] = value;
++_size;
}
else
throw logic_error("Valid insert index is from 0 to Size");
}
#endif /* _ARRAYLIST_ */
下面是测试代码:
#include "ArrayList.cpp"
void ArrayListTest1();
void Test( void (*fp)() );
int main(int argc, char** argv)
{
Test(ArrayListTest1);
return 0;
}
void ArrayListTest1()
{
ArrayList<int> v;
int removed = 0 ;
v.Print();
v.Add(5);
v.Add(8);
v.Add(10);
v.Print();
v.Insert(3,20);
v.Print();
v.Insert(1,22);
v.Print();
v.Insert(0,28);
v.Print();
v.Add(101);
v.Add(102);
v.Add(103);
v.Add(104);
v.Print();
removed = v.Remove();
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(105);
v.Print();
removed = v.Remove(0);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(106);
removed = v.Remove(v.Size()-1);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(107);
removed = v.Remove(5);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(109);
v.Add(110);
v.Print();
for(int i=9;i>0;--i)
v.Insert(11,110+i);
v.Print();
v.Insert(11,150);
v.Print();
for(int i=0;i<v.Size();++i)
cout<< v[i] << ",";
cout<<endl;
v.Remove(30);
}
void Test( void (*fp)() )
{
try
{
fp();
}
catch(out_of_range e)
{
cout<< "Catch Exception:" << e.what() << endl;
}
catch(logic_error e)
{
cout<< "Catch Exception:" << e.what() << endl;
}
}
下面是测试结果:
Size=0
Capacity=10
0,0,0,0,0,0,0,0,0,0,
Size=3
Capacity=10
5,8,10,
5,8,10,0,0,0,0,0,0,0,
Size=4
Capacity=10
5,8,10,20,
5,8,10,20,0,0,0,0,0,0,
Size=5
Capacity=10
5,22,8,10,20,
5,22,8,10,20,0,0,0,0,0,
Size=6
Capacity=10
28,5,22,8,10,20,
28,5,22,8,10,20,0,0,0,0,
Size=10
Capacity=10
28,5,22,8,10,20,101,102,103,104,
28,5,22,8,10,20,101,102,103,104,
Size=9
Capacity=10
28,5,22,8,10,20,101,102,103,
28,5,22,8,10,20,101,102,103,104,
Removed=104
Size=10
Capacity=10
28,5,22,8,10,20,101,102,103,105,
28,5,22,8,10,20,101,102,103,105,
Size=9
Capacity=10
5,22,8,10,20,101,102,103,105,
5,22,8,10,20,101,102,103,105,0,
Removed=28
Size=9
Capacity=10
5,22,8,10,20,101,102,103,105,
5,22,8,10,20,101,102,103,105,0,
Removed=106
Size=9
Capacity=10
5,22,8,10,20,102,103,105,107,
5,22,8,10,20,102,103,105,107,0,
Removed=101
Size=11
Capacity=20
5,22,8,10,20,102,103,105,107,109,110,
5,22,8,10,20,102,103,105,107,109,110,0,0,0,0,0,0,0,0,0,
Size=20
Capacity=20
5,22,8,10,20,102,103,105,107,109,110,111,112,113,114,115,116,117,118,119,
5,22,8,10,20,102,103,105,107,109,110,111,112,113,114,115,116,117,118,119,
Size=21
Capacity=40
5,22,8,10,20,102,103,105,107,109,110,150,111,112,113,114,115,116,117,118,119,
5,22,8,10,20,102,103,105,107,109,110,150,111,112,113,114,115,116,117,118,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5,22,8,10,20,102,103,105,107,109,110,150,111,112,113,114,115,116,117,118,119,
Catch Exception:Index is out of range