C++实现数组构造的线性表

#include<iostream>
#include<algorithm>//copy,copy_backward函数
#include<sstream> //ostringstream
#include<string> //字符串
#include<exception>//异常处理
#include<iterator> //ostream_iterator<T>输出流

using namespace::std;
//改变二维数组的长度,每一维都可以变化
/*template<typename T>
void changeLength2D(T ** &a, unsigned oldRow,unsigned oldCol,unsigned newRow, unsigned newCol)
{
	T **b = new T*[newRow];
	for (unsigned i = 0; i != newRow; ++i)
		b[i] = new T[newCol];
	unsigned row, col;
	row = min(oldRow, newRow);
	col = min(oldCol, newCol);
	for (unsigned i = 0; i != row; ++i)
	{
		copy(a[i], a[i]+col,b[i]);
	}
	for (unsigned i = 0; i != oldRow; ++i)
	{
		delete[] a[i];
	}
	delete[] a;
	a = b;
}*/
//异常类
/*class illegalParameterValue
{
public:
	illegalParameterValue():
		message("Illegal parameter value") { }
	illegalParameterValue(char* theMessage)
	{
		message = theMessage;
	}
	void outputMessage() { cout << message << endl; }
private:
	string message;
};*///和上面的类做区别s.str()是代表的具体类容,因此不可用上面的(直接赋语句却是可以的)
class illegalParameterValue
{
public:
	illegalParameterValue(string theMessage = "Illegal parameter value")
	{
		message = theMessage;
	}
	void outputMessage() { cout << message << endl; }
private:
	string message;
};
class illegalIndex
{
public:
	illegalIndex(string theMessage = "Illegal index") //初始化
	{
		message = theMessage;
	}
	void outputMessage() { cout << message << endl; }
private:
	string message;
};
//在类arayList中增加一个构造函数,允许你指定一个值,当数组空间满时改变该数组长度
template<typename T>
class arrayList//:public linearList<T>
{
public:
	//构造函数,新加的构造函数,析构函数
	arrayList(int initialCapacity = 10);
	arrayList(unsigned theLengthChange = 0, int initialCapacity = 10);
		~arrayList() { delete[] element; }
	//ADT方法
	void insert(int theIndex, const T& theElement);
	void changeLength1D(T* &a, int oldLength, int newLength);
	void output(ostream& out) const;
	void trimToSize();
	T  operator[](const int i);
	void push_back(const T& thelement);
	void pop_back();
	void clear();
	int lastIndexof(const T& theElement);
	void reverse();
	void circularShift(int i);
private:
	T* element;
	int arrayLength;
	int listsize;
	unsigned LengthChange;


};
//构造函数以及其他函数的定义
template<typename T>
arrayList<T>::arrayList(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity=" << initialCapacity << "Must be >0";
		throw illegalParameterValue(s.str());//s.str(()返回s中储存的string 对象
	}
	arrayLength = initialCapacity;
	element = new T[arrayLength];
	listsize = 0;
	LengthChange = 0;     //一定要保证类的private的值都有值,即使为0
}
//多增加了要改变的长度
template<typename T>
arrayList<T>::arrayList(unsigned theLengthChange,int initialCapacity)
{
	if (initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity=" << initialCapacity << "Must be >0";
		throw illegalParameterValue(s.str());//s.str(()返回s中储存的string 对象
	}
	arrayLength = initialCapacity;
	element = new T[arrayLength];
	listsize = 0;
	LengthChange = theLengthChange;
}
//插入函数
template<typename T>
 void arrayList<T>::insert(int theIndex, const T& theElement)
	{
		if (theIndex<0 || theIndex>listsize)
		{
			ostringstream s;
			s <<"index= " << theIndex << "size= " << listsize;
			throw illegalIndex(s.str());
		}
		if (LengthChange)
		{
			changeLength1D(element, arrayLength, LengthChange);
			arrayLength = LengthChange;
		}
		else
		{
			changeLength1D(element, arrayLength, 2*arrayLength);
			arrayLength *=2;
		}
		//把theIndex之后的元素向后移动一位
		copy_backward(element + theIndex, element + listsize, element + listsize + 1);
		element[theIndex] = theElement;
		listsize++;
}
//改变一维数组长度的函数
template<typename T>
void  arrayList<T>::changeLength1D(T* &a, int oldLength, int newLength)
{
	if (newLength < 0)
		throw illegalParameterValue("new lenght must be>=0");
	T*temp = new T[newLength];
	int number = min(oldLength, newLength);
	copy(a, a + number, temp);
	delete[] a;
	a = temp;
}
//输出函数
template<typename T>
void  arrayList<T>::output(ostream& cout) const
{
	copy(element, element + listsize, ostream_iterator<T>(cout, " "));
}
//使数组长度大小为max(size,1)
template<typename T>
void arrayList<T>::trimToSize()
{
	int size = max(listsize, 1);
	T *b = new T[size];
	copy(element, element + size, b); //复杂度为O(listSize);
	delete[] element;
	element = b;
}
//重载操作符[]
template<typename T>
T arrayList<T>::operator[](const int i)
{
	if (i<0 || i>listsize)
	{
		ostringstream s;
			s << "i=" << i;
		throw illegalIndex(s.str());
	}
return element[i];
}
//编写方法push_back,把元素插入到线性表的右端
template<typename T>
void arrayList<T>::push_back(const T& thelement)
{
	element[listsize]= thelement; //复杂度O(1)
	listsize++;
}
//编写方法pop_back,把右端的元素删除
template<typename T>
void arrayList<T>::pop_back()
{
	element[--listsize].~T();//删除最后一个元素复杂度O(1)
}
//编写方法,将线性表清空
template<typename T>
void arrayList<T>::clear()
{
	for(int i=listsize-1;i>=0;i--)  //复杂度O(listsize)
		element[--listsize].~T();
}
//编写寻找函数,借助于函数find(可以找到元素第一次出现的迭代器),要找到元素最后出现的索引
template<typename T>
int arrayList<T>::lastIndexof(const T& theElement)
{
	int i = listsize,j=0,theIndex=listsize;                     //这样初始化(不选择0)是为了确保要找的元素就是第一个元素而不出错
	do                                                          //而且也保证了如果没有元素匹配时有判断条件,变成while的,i=0就会有两种情况,要么在首位,要么无要找的元素
	{
		i = theIndex;
		theIndex = (int)(find(element + j, element + listsize, theElement) - element);//方法的时间复杂度为O(n)(最坏)
		j=theIndex+1;
	} while (theIndex < listsize);
		if (i==listsize)
			return -1;
	else return i;
}
//编写原地颠倒函数,不用STL中的reverse
template<typename T>
void arrayList<T>::reverse()
{
	T a;
	for (int i = 0; i < listsize/2; i++)  //交换了listsize/2,复杂度O(listsize/2)
	{
		a = element[i];
		element[i] = element[listsize - i - 1];
		element[listsize-i-1] = a;
	}


}
//编写循环移动函数(顺时针旋转)
template<typename T>
void arrayList<T>::circularShift(int i)
{
	T* b = new T[listsize];
	while(i)
	{
		  copy(element, element + listsize, b);
			for (int j = 0; j < listsize-1; j++)
		    {
			   element[j] = b[j+1];
		   }
			element[listsize - 1] = b[0];
		   i--;
	}
	delete[] b;
}


int main()
{
	/*//对二维数组的改变进行测试
	int row = 2, col = 3;
	int temp[2][3]= { 1, 2, 3, 4, 5, 6 };
	//给数组a分配空间
	int **a = new int*[row];
	for (size_t i = 0; i != row; ++i)
	{
		a[i] = new int[col];
	}
	//用temp给数组初始化
	for (size_t i = 0; i != row; ++i)
		for (size_t j = 0; j != col; ++j)
			a[i][j] = temp[i][j];        
	changeLength2D(a, 2, 3, 3, 4);
	//给未复制到的元素赋值,只有在新数组长度大于原数组长度时才用
	for (size_t i = 0; i != 3; ++i)
		for (size_t j = 3; j != 4; ++j)
			a[i][j] = 0;
	for (size_t i = 2; i != 3; ++i)
		for (size_t j = 0; j != 4; ++j)
			a[i][j] = 0;
	//输出新的数组的值
	for (size_t i = 0; i != 3; ++i)
	{
		for (size_t j = 0; j != 4; ++j)
		{
          cout << a[i][j] << ' ';
		}
		cout << '\n';
	}*/
	//对插入函数进行测试
	//arrayList<int>y(3);
	/*arrayList<int>y(6,3);  //第一位表示要更改的数组长度,第二位表示原长度
	y.insert(0, 2);
	y.insert(1, 6);
	y.insert(0, 1);
	y.insert(2, 4);
	y.insert(3, 5);
	y.insert(2, 3);
	y.output(cout);*/
	//对改变数组长度进行测试
	/*arrayList<int>y(10);
	y.insert(0, 2);
	y.insert(1, 6);
	y.trimToSize();
	//异常抛出测试
	try { y.insert(3, 0); }
	catch (illegalIndex e)
	{
		cout << "Illegal index exception" << endl;
		cout << "Insert index must be between 0 and list size" << endl;
		e.outputMessage();
	}*/
	//测试重载操作符[]
	/*arrayList<int>y(3);
	y.insert(0, 2);
	y.insert(1, 6);
    int s=y[1];
	//测试异常抛出
	try { y[6]; }
	catch (illegalIndex e)
	{
		cout << "Illegal index exception" << endl;
		e.outputMessage();
	}
	cout <<s<<endl;*/
	//测试push_back
	/*arrayList<int>y(3);
	y.push_back(2);
	y.push_back(3);
	//测试pop_back
	y.pop_back();
	//测试清空
	y.clear();
	y.output(cout);*/
	//对lastIndexOf函数进行测试5
	arrayList<int>y(10);
	y.push_back(0);
	y.push_back(1);
	y.push_back(2);
	y.push_back(3);
	y.push_back(4);
	/*int i = y.lastIndexof(4);
	cout << i << endl;*/
	//原地颠倒测试
	//y.reverse();
	//循环移动测试
	y.circularShift(2);
	y.output(cout);

	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值