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

来源:互联网 发布:sql去重复查询多个字段 编辑:程序博客网 时间:2024/06/12 09:24
#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中的reversetemplate<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_backy.pop_back();//测试清空y.clear();y.output(cout);*///对lastIndexOf函数进行测试5arrayList<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;}


原创粉丝点击