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__

代码当中的问题及思考提示将在下一篇文章中探讨。

posted @ 2017-04-04 22:22  滴巴戈  阅读(1116)  评论(0编辑  收藏  举报