通过类模板实现顺序表时,若进行比较和遍历操作,模板元素可以通过STL中的equal_to仿函数实现,或者通过回调函数实现。若进行复制操作,可以采用STL的算法函数,也可以通过操作地址实现。关于回调函数和地址操作可以查看:C语言利用动态数组实现顺序表(不限数据类型)
主要功能:初始化,按照索引插入,删除,遍历,按索引返回元素,返回顺序表的容量,元素个数,及扩容操作。
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 5 6 using namespace std; 7 8 //异常类 9 class illegalParameterValue{ 10 public: 11 illegalParameterValue(); 12 illegalParameterValue(string myMessage); 13 void outPutMessage(); 14 private: 15 string message; 16 }; 17 18 illegalParameterValue::illegalParameterValue(){ 19 this->message = "illegal Parameter Value"; 20 } 21 22 illegalParameterValue::illegalParameterValue(string myMessage){ 23 this->message = myMessage; 24 } 25 26 void illegalParameterValue::outPutMessage(){ 27 cout << this->message << endl; 28 } 29 30 //自定义顺序表类模板 31 template<class T> 32 class arrayList{ 33 public: 34 //构造函数 35 arrayList(); 36 arrayList(int iniCapacity); 37 //复制构造函数 38 arrayList(const arrayList<T>& theList); 39 40 ~arrayList(){ delete[] element; } 41 42 //ADT方法 43 int mySize() const { return this->arrayListSize; } 44 int myCapacity() const { return this->arrayListCapacity; } 45 bool myEmpty() const { return arrayListSize == 0; } 46 47 void myForeach() const; 48 T& myGet(int index) const; 49 void myErasePos(int index); 50 void myEraseValue(T& theElement); 51 void myInsert(int index, T& theElement); 52 void output(ostream& out)const; 53 private: 54 int arrayListCapacity; 55 int arrayListSize; 56 T* element; 57 }; 58 59 //构造函数,抛出异常时需要注意释放已创建的动态数据 60 //如果抛出异常后,没有处理,会继续向上抛出,直到main函数处理 61 //这里只是抛出,并没有捕获,因此不会显示message 62 template <class T> 63 arrayList<T>::arrayList(){} 64 65 template <class T> 66 arrayList<T>::arrayList(int iniCapacity){ 67 if (iniCapacity < 1) 68 { 69 string message = "the iniCapacity must be > 0"; 70 throw illegalParameterValue(message); 71 } 72 //throw 1; 73 arrayListCapacity = iniCapacity; 74 element = new T[arrayListCapacity]; 75 arrayListSize = 0; 76 } 77 78 template <class T> 79 arrayList<T>::arrayList(const arrayList<T>& theList){ 80 arrayListCapacity = theList.arrayListCapacity; 81 arrayListSize = theList.arrayListSize; 82 element = new T[arrayListCapacity]; 83 copy(theList.element, theList.element + arrayListSize, element); 84 } 85 86 //ADT方法 87 //根据pos获取元素 88 template<class T> 89 T &arrayList<T>::myGet(int index)const{ 90 if (index < 0 || index >= arrayListSize){ 91 throw illegalParameterValue("the index is wrong."); 92 } 93 return element[index]; 94 } 95 96 //按位置删除元素 97 template <class T> 98 void arrayList<T>::myErasePos(int index){ 99 if (index < 0 || index >= arrayListSize){ 100 throw illegalParameterValue("the index is wrong."); 101 } 102 //整体移动 103 copy(element + index + 1, element + arrayListSize, element+ index ); 104 arrayListSize--; 105 } 106 107 //按值删除,仅删除第一次出现的位置,通过equal_to实现 108 template <class T> 109 void arrayList<T>::myEraseValue(T &theElement){ 110 111 for (int i = 0; i != arrayListSize; i++){ 112 if (equal_to<T>()(element[i], theElement)){ 113 114 cout << "mid" << endl; 115 myErasePos(i); 116 break; 117 } 118 } 119 } 120 121 //按位置插入元素,并扩容 122 //这里有个非常隐蔽的错误,tmpElement通过new开辟内存空间 123 //按道理需要释放tmpElement,但tmpElement的地址赋给element,两个变量指向同一个内存地址 124 //element本身运行或下次进入条件就会析构掉,释放掉该块内存 125 //如果提前释放掉tmpElement,则提前释放了该块内存,则会二次释放造成内存泄漏 126 template <class T> 127 void arrayList<T>::myInsert(int index, T &theElement){ 128 if (index < 0 || index > arrayListSize){ 129 throw illegalParameterValue("the index is wrong."); 130 } 131 132 if (arrayListSize >= arrayListCapacity){ 133 int tmpCapacity = arrayListCapacity * 2; 134 T *tmpElement = new T[tmpCapacity]; 135 copy(this->element, this->element+this->arrayListSize, tmpElement); 136 this->~arrayList(); 137 this->element = tmpElement; 138 arrayListCapacity = arrayListCapacity * 2; 139 //delete [] tmpElement; 140 } 141 copy_backward(this->element + index, this->element + arrayListSize, this->element + arrayListSize + 1); 142 this->element[index] = theElement; 143 arrayListSize++; 144 } 145 146 //输出函数 147 template <class T> 148 void arrayList<T>::output(ostream& out)const{ 149 copy(element, element + arrayListSize, ostream_iterator<T>(out, " ")); 150 } 151 //重载<< 152 template <class T> 153 ostream& operator<<(ostream& out, const arrayList<T>& x){ 154 x.output(out); 155 return out; 156 } 157 158 int main(){ 159 arrayList<int>mylist(2); 160 int a1 = 1, a2 = 2, a3 = 3; 161 162 mylist.myInsert(0, a1); 163 mylist.myInsert(1, a2); 164 mylist.myInsert(2, a3); 165 166 mylist.myErasePos(0); 167 int b = 2; 168 mylist.myEraseValue(b); 169 mylist.output(cout); 170 cout << endl; 171 172 cout << mylist.myGet(1) << endl; 173 mylist.output(cout); 174 175 system("pause"); 176 return 0; 177 }