数据结构——线性结构(9)——Vector的实现过程详解
2017-10-22 15:56
633 查看
vector的基本操作及其特点
在实现vector之前,我们都知道vector是可以储存任意类型的数值的。为了实现更一般的数据操作,我们当然是得要用模板类代替传统的实现。并且我们要实现[ ]的重载。头文件
/* *这个文件包含我们Vector类的模板类的声明,vector是一个高效,方便,安全的数组替代品 */ #ifndef _Vector_h #define _Vector_h template<typename ValueType> /* *这个类能储存一系列的元素,并可以随时对它们进行增删查改 *它能提供传统的一些选择运算符的重载 *它能提供一些处理数组常用到的方法 */ class Vector{ public: /* *函数:构造函数 *用法:Vector<ValueType> vec :Vector<ValueType> vec(n,value) 创建n相同的value数组 *------------------------------------------------------- *初始化一个空的vector */ Vector(); Vector(int n, ValueType value = ValueType());//后面这一句,调用默认构造函数 //用来初始化对应类型的初始值 /* *函数:析构函数 *用法:隐式调用 *--------------------------------------------------- *用于释放动态分配中的所占用的堆的内存 */ ~Vector(); /* *方法:size() *用法:int i = vec.size() *---------------------------------- *返回vector中的元素个数 */ int size(); /* *方法:isEmpty() *用法:if(vec.isEmpty()) *---------------------------------- *判断vector是否为空 */ bool isEmpty(); /* *方法:clear() *用法:vec.clear *---------------------------------- *清空vector中的元素 */ void clear(); /* *方法:get(int index) *用法:valueType value = vec.get(index) *---------------------------------- *返回vector中指定下标的元素,如果指定的下标越界,那么返回一个错误 */ ValueType get(int index); /* *方法:set(index,value) *用法:vec.set(index,value) *---------------------------------- *用后面的元素替代指定下标的元素,如果指定的下标越界,那么返回一个错误 */ void set(int index, ValueType value); /* *方法:insertAt(index,value) *用法:vec.insertAt(index,value) *---------------------------------- *在指定下标的元素之前插入元素value,如果指定的下标越界,那么返回一个错误 */ void insertAt(int index, ValueType value); /* *方法:removeAt(index) *用法:vec.removeAt(index) *---------------------------------- *移除指定下标的元素,如果指定的下标越界,那么返回一个错误 */ void removeAt(int index); /* *方法:add(value) *用法:vec.add(value) *---------------------------------- *在数组末尾添加一个元素 */ void add(ValueType vale); /* *运算符[] *用法vec[index] *------------------- *重载运算符,使得我们能在vector中选择我们要处理的元素,如果我们指定的范围 *超出了我们的指定下标,那么我们 *返回一个错误 */ ValueType &operator[](int index); #include "Vectorpriv.h" }; #include "Vectorimpl.cpp" #endif
私有部分文件Vectorpriv.h
/*这个文件包含了我们vector接口的私有部分*/ /* *实现说明:Vector的数据结构 *------------------------ *vector的数据是储存在我们的动态数组中,而且当我们动态数组满了的时候,我们实现双倍扩容的操作 */ private: static const int INITIAL_CAPACITY = 10; /*实例化变量*/ ValueType *array; //指向动态数组的指针 int capacity; //数组被分配的容量 int count; //使用中的元素的个数(即数组元素的个数) /*私有方法声明*/ void expandCapacity(); /* Make it illegal to copy vectors */ Vector(const Vector & value) { } const Vector & operator=(const Vector & rhs) { return *this; }
实现部分Vectorimpl.cpp
/* *这个文件包含了我们Vector接口的功能实现 */ #ifdef _Vector_h #include "error.h" /* *实现说明:构造函数与析构函数 *首先,这两个构造函数的实现都是先在堆中为动态数组分配空间,并且为我们的对象成员赋予初始值 *而我们的析构函数则释放我们之前申请的那段空间 */ template <typename ValueType> Vector<ValueType>::Vector(){ capacity = INITIAL_CAPACITY; count = 0; array = new ValueType[capacity]; } template <typename ValueType> Vector<ValueType>::Vector(int n, ValueType value){ //这里注意,因为n是用户输入的,很有可能会大于我们预设的容量,所以要进行判断 capacity = (n > INITIAL_CAPACITY) ? n :INITIAL_CAPACITY; array = new ValueType[capacity]; count = n; //将value值全部复制在我们在堆中new出来的空间内 for (int i = 0; i < n; i++) { array[i] = value; } } template <typename ValueType> Vector<ValueType>::~Vector(){ delete []array; } /* *Vector的基本操作实现 */ template <typename ValueType> int Vector<ValueType>::size(){ return count; } template <typename ValueType> bool Vector<ValueType>::isEmpty(){ return count == 0; } template <typename ValueType> void Vector<ValueType>::clear(){ d454 return count = 0; } template <typename ValueType> ValueType Vector<typename ValueType>::get(int index){ if (index >= count || index < 0) { error("get: index out of range"); } return array[index]; } template <typename ValueType> void Vector<ValueType>::set(int index,ValueType value){ if (index >= count || index < 0) { error("set: index out of range"); } array[index] = value; } /*选择运算符重载 *这里为了我们不但能查看,还能引用这里的值,所以我们用的是&符号 */ template <typename ValueType> ValueType & Vector<ValueType>::operator[](int index) { if (index < 0 || index >= count) { error("Vector selection index out of range"); } return array[index]; //引用返回堆中的对应下标的值 } /* *实现说明 : add insertAt removeAt *这些方法必须移动数组中的现有元素,为新元素腾出空间,或者关闭被删除元素留下的空间 */ template<typename ValueType> void Vector<ValueType>::add(ValueType value){ insertAt(count,value); } template<typename ValueType> void Vector<ValueType>::insertAt(int index, ValueType value){ if (index == count) expandCapacity();//如果这里写成 = 那么这个功能就变成了add if (index > count || index < 0) error("insertAt: index out of range"); //反向遍历,并且所有元素后移一位 for (int i = count; i > index; i--){ array[i] = array[i - 1]; } array[index] = value; count++; } template<typename ValueType> void Vector<ValueType>::removeAt(int index){ if (index >= count || index < 0) error("removeAt: index out of range"); /*顺序遍历,并将所有的元素前移一位,这里如果反向遍历会麻烦一点 *为什么不能是count?因为我们后面用的是i+1, * i < count的最大整数就是 count -1,所以count -1 +1 = count * 取array[count] 越界! */ for (int i = index; i < count - 1; i++) { array[i] = array[i + 1]; } count--; } //扩展容量五部曲 template<typename ValueType> void Vector<ValueType>::expandCapacity(){ ValueType *oldArray = array; capacity = capacity * 2; array = new ValueType[capacity]; for (int i = 0; i < count; i++) { array[i] = oldArray[i]; } delete[] oldArray; } #endif
测试代码及结果:
#include <iostream> #include "Vector.h" using namespace std; int main(){ Vector<int> vec(4,9);//9 9 9 9 vec.insertAt(2,0); //9 9 0 9 9 vec.add(4);//9 9 0 9 9 4 vec.removeAt(3);//9 9 0 9 4 for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; } return 0; }
对removeAt和insertAt的一些思考
insertAt的理解(主要是for循环条件的思考):2.removeAt的理解(主要是for循环条件的思考):
没错,就是插入排序算法的原理!!
相关文章推荐
- Java数据结构与算法—及实现 线性表 顺序表、链表、栈、队列详解
- 数据结构1:线性表的顺序表示和实现
- [数据结构一]线性表:顺序实现
- 数据结构教程 第六课 线性表的顺序表示和实现
- 数据结构之线性表实现
- 数据结构教程 第八课 线性表的链式表示与实现
- SQLServer实现树型结构数据查询的存储过程,类似oracle的connect by
- 数据结构之线性表――链式存储结构之单链表(php代码实现)
- 数据结构之线性表顺序实现
- 数据结构二:线性表的顺序结构实现
- 数据结构—线性结构—线性及其实现
- 数据结构之:线性表的顺序表示和实现
- 数据结构之线性表实现
- 数据结构之线性表――顺序存储结构(php代码实现)
- 数据结构—线性表的链式表示和实现
- 数据结构实现顺序线性表的一些小应用
- 数据结构算法代码实现——线性表的链式表示与实现(单链表)(三 )
- 线性表的顺序表示和实现 - 数据结构
- jarson jQuery的deferred对象使用详解——实现ajax线性请求数据
- 数据结构,图的邻接矩阵创建,邻接矩阵与邻接表的交换,两种表的输出,过程用C++实现