数据结构——线性结构(9)——Vector的实现过程详解
来源:互联网 发布:淘宝幸运抽奖 编辑:程序博客网 时间:2024/06/04 20:12
vector的基本操作及其特点
在实现vector之前,我们都知道vector是可以储存任意类型的数值的。为了实现更一般的数据操作,我们当然是得要用模板类代替传统的实现。并且我们要实现[ ]的重载。
头文件
/* *这个文件包含我们Vector类的模板类的声明,vector是一个高效,方便,安全的数组替代品 */#ifndef _Vector_h#define _Vector_htemplate<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(){ 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循环条件的思考):
没错,就是插入排序算法的原理!!
阅读全文
1 0
- 数据结构——线性结构(9)——Vector的实现过程详解
- 数据结构—线性结构—线性及其实现
- 数据结构——线性结构(8)——动态数组与Vector
- [数据结构]线性结构——线性表
- 数据结构——线性结构
- 数据结构——线性结构(1)——顺序栈的实现
- 数据结构——线性结构(3)——链栈的实现
- 数据结构——线性结构(5)——顺序队列的实现
- 数据结构——线性结构(7)——链队列的实现
- 大话数据结构(二)——线性表链式存储结构(单链表)的java实现
- 大话数据结构(一)——线性表顺序存储结构的java实现
- 【数据结构】数据结构与算法(一)——线性结构
- 数据结构——线性表的实现
- 线性结构————数据结构
- 数据结构——线性表——顺序存储结构——C++实现线性表
- 数据结构——线性表——链式存储结构——C++实现线性表
- [数据结构]线性结构——队列
- [数据结构]线性结构——栈
- pandas/sklearn入门指南
- 考试易错点&&注意事项
- 严蔚敏数据结构——算法2.7改进
- Java数组越界错误:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
- 面试经验
- 数据结构——线性结构(9)——Vector的实现过程详解
- Codeforces Round #193 (Div. 2)
- FPGA自动售货机设计
- JavaScript 基础学习01
- 《每天学一个设计模式》 之 策略模式
- ccleaner后门完全分析报告
- 网络(HTTP与HTTPS的区别)
- 数据库中存储过程语法
- staticmethod和classmethod的区别