C++实现动态顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的。只要知道了第一个元素的存储地址,就可以知道线性表中任何一个元素的存储地址。本文利用C++语言,在Windows平台 Visual Studio 2015开发环境下实现。功能:应用C++语言实现顺序表的各项操作。基本的成员函数:构造函数、拷贝构造函数、赋值运算符的重载、析构函数。
// 顺序表构造成功之后,里面存放了n个元素data
Vector(size_t n, const DataType& data = DataType());
Vector(const Vector& v);
Vector& operator=(const Vector& v);
~Vector();
void PushBack(const DataType& data); //尾插
void PopBack(); //尾删
void Print()//打印顺序表
// 给顺序表重新赋值,该函数执行完里面存放了n个元素data
void Assign(size_t n, const DataType& data);
// 在顺序表的pos位置上插入元素data
void Insert(size_t pos, const DataType& data);
// 删除顺序表pos位置上的元素
void Erase(size_t pos);
// 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间用data来填充
void ReSize(size_t n, const DataType& data = DataType());
// 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间
void Clear();
// 返回顺序表中有效元素的大小
size_t Size()const;
// 返回顺序表中空间容量的大小
size_t Capacity()const;
// 顺序表是否为空,若为空返回true,否则返回null
bool Empty()const;
// 通过下边访问顺序表index位置上的元素。 思考为什么要成对的来重载
DataType& operator[](size_t index);
const DataType& operator[](size_t index)const;
// 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载
DataType& Front();
const DataType& Front()const;
// 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载
DataType& Back();
const DataType& Back()const;
void _CheckCapacity()// 动态扩容
int Find(const DataType & data)//查找数据
1 #ifndef __VECTOR_H__ 2 #define __VECTOR_H__ 3 4 #include<iostream> 5 #include<stdio.h> 6 #include<assert.h> 7 using namespace std; 8 9 #define COW 4 10 typedef int DataType; 11 12 class Vector 13 { 14 public: 15 Vector() 16 : _array(NULL) 17 , _size(0) 18 , _capacity(0) 19 {} 20 21 // 顺序表构造成功之后,里面存放了n个元素data 22 Vector(size_t n, const DataType& data = DataType()) 23 { 24 _array = new DataType[n]; 25 _size = n; 26 _capacity = n; 27 for(size_t i = 0; i<n;i++) 28 _array[i] = data; 29 30 } 31 Vector(const Vector& v) 32 :_array(new DataType[v._size]) 33 , _size(v._size) 34 ,_capacity(v._capacity) 35 { 36 memcpy(_array, v._array, sizeof(DataType)*_size); 37 } 38 Vector& operator=(const Vector& v) 39 { 40 if (this != &v) 41 { 42 DataType *temp = new DataType[v._size]; 43 temp = v._array; 44 delete[] _array; 45 _array = temp; 46 _size = v._size; 47 _capacity = v._capacity; 48 memcpy(_array, v._array, sizeof(DataType)*_size); 49 } 50 return *this; 51 } 52 ~Vector() 53 { 54 if (_array) 55 { 56 delete[] _array; 57 _array = NULL; 58 _size = 0; 59 _capacity = 0; 60 } 61 } 62 63 public: 64 void PushBack(const DataType& data) 65 { 66 _CheckCapacity(); 67 _array[_size++] = data; 68 } 69 void PopBack() 70 { 71 assert(!Empty()); 72 --_size; 73 } 74 void Print() 75 { 76 for (size_t i = 0; i < _size; ++i) 77 { 78 cout << _array[i] << " "; 79 } 80 cout << endl; 81 } 82 // 给顺序表重新赋值,该函数执行完里面存放了n个元素data 83 void Assign(size_t n, const DataType& data) 84 { 85 assert(n<_size); 86 for (size_t i = 0; i<n; i++) 87 _array[i] = data; 88 } 89 90 // 在顺序表的pos位置上插入元素data 91 void Insert(size_t pos, const DataType& data) 92 { 93 assert(pos<_size); //需检验pos的合法性 94 _CheckCapacity(); 95 if (pos == _size - 1) //在最后一个位置插入数据等于尾插 96 { 97 PushBack(data); 98 return; 99 } 100 else 101 { 102 for (size_t i = _size; i > pos; --i) 103 { 104 _array[i] = _array[i - 1]; 105 } 106 _array[pos] = data; 107 _size++; 108 } 109 } 110 111 // 删除顺序表pos位置上的元素 112 void Erase(size_t pos) 113 { 114 assert(pos<_size); //需检验pos的合法性 115 if (pos == _size - 1) //在最后一个位置删除数据等于尾删 116 { 117 PopBack(); 118 return; 119 } 120 else 121 { 122 for (size_t i = pos; i < _size - 1; i++) 123 { 124 _array[i] = _array[i + 1]; 125 } 126 --_size; 127 } 128 } 129 130 // 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间 131 // 请用data来填充 132 void ReSize(size_t n, const DataType& data = DataType()) 133 { 134 if (n > _size) 135 { 136 size_t i = _size; 137 _size = n; 138 _CheckCapacity(); 139 for (i; i < n; i++) 140 _array[i] = data; 141 } 142 else 143 { 144 size_t i = n; 145 for(i; i<_size; i++) 146 PopBack(); 147 } 148 } 149 150 // 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间 151 void Clear() 152 { 153 delete[] _array; 154 _array = NULL; 155 _size = 0; 156 _capacity = 0; 157 } 158 // 返回顺序表中有效元素的大小 159 size_t Size()const 160 { 161 return _size; 162 } 163 // 返回顺序表中空间容量的大小 164 size_t Capacity()const 165 { 166 return _capacity; 167 } 168 // 顺序表是否为空,若为空返回true,否则返回null 169 bool Empty()const 170 { 171 return _size == 0; 172 } 173 174 // 通过下边访问顺序表index位置上的元素 175 // 思考为什么要成对的来重载 176 DataType& operator[](size_t index) 177 { 178 assert(index); 179 return _array[index]; 180 } 181 const DataType& operator[](size_t index)const 182 { 183 assert(index); 184 return _array[index]; 185 } 186 // 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载 187 DataType& Front() 188 { 189 return _array[0]; 190 } 191 const DataType& Front()const 192 { 193 return _array[0]; 194 195 } 196 // 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载 197 DataType& Back() 198 { 199 return _array[_size - 1]; 200 } 201 const DataType& Back()const 202 { 203 return _array[_size - 1]; 204 } 205 private: 206 // 动态扩容-->该函数中有坑,请找出坑在哪? 207 void _CheckCapacity() 208 { 209 // 2*_capacity 有问题? 210 if (_size >= _capacity) 211 { 212 DataType* pTemp = new DataType[_capacity * 2]; 213 //memcpy(pTemp, _array, _size*sizeof(DataType)); 214 for (size_t index = 0; index < _size; ++index) 215 pTemp[index] = _array[index]; 216 delete[] _array; 217 _array = pTemp; 218 _capacity *= 2; 219 } 220 } 221 int Find(const DataType & data) 222 { 223 assert(_array != NULL); 224 for (size_t i = 0; i < _size; i++) 225 { 226 if (_array[i] == data) 227 return i; 228 } 229 return -1; 230 } 231 private: 232 DataType* _array; 233 size_t _size; // 保存有效元素的个数 234 size_t _capacity; // 空间的实际大小 235 }; 236 237 #endif //__VECTOR_H__
代码当中的问题及思考提示将在下一篇文章中探讨。