数据结构
通过一些特定的数据结构,我们可以高效的存储大量数据
从底层来讲,数据结构其实分为两种:顺序和链式,也就是数据成员是否互相挨着
接下来我们来讲述Vector
Vector
Vector的特点:
- 本质就是一个数组
- 可以动态扩充容量
- 支持下标方法,这也意味着该数据结构存储的数据是连续的,查询性能好
- 新增数据和删除数据的性能 较差
现在我们来实现该数据结构
如下是通过模板们实现的该数据结构部分功能,我们可以根据该模板进行下一步的实现与优化
#define SUCCESS 0
#define ERROR -1
#define NEW_ERROR -2
#define INDEX_ERROR -3
template<typename T_ELE>
class Vector
{
public: //构造函数与析构函数
Vector();
Vector(DWORD dwSize);
~Vector();
public: //公开成员方法
DWORD at(DWORD dwIndex, OUT T_ELE * pElement); //根据给定的索引得到元素
DWORD push_back(T_ELE element); //将element添加到最后一个位置
T_ELE pop_back(); //删除最后一个元素
DWORD insert(DWORD dwIndex, T_ELE pElement); //向指定位置插入element
DWORD erase(DWORD dwIndex); //删除指定元素
DWORD capacity(); //返回剩余空间
VOID clear(); //清除所有元素
BOOL empty(); //判断vector是否为空
DWORD size(); //返回vector的大小
private: //私有成员方法
BOOL expand(); //vector扩容
private: //私有变量
DWORD m_dwIndex; //下一对象的索引
DWORD m_dwIncrement; //每次扩容的对象数量
DWORD m_dwLen; //当前容器对象数量
DWORD m_dwInitSize; //默认容器中对象的数量
T_ELE* m_pVector; //容器指针
};
template<class T_ELE>
Vector <T_ELE>::Vector()::m_dwInitSize(100), m_dwIncrement(5) //初始化类成员
{
m_pVector = new T_ELE[m_dwInitSize];//在堆中创建长度为m_dwInitSize个T_ELE对象
memset(m_pVector, 0, sizeof(Vector) * m_dwInitSize); //将创建的堆空间初始化
m_dwLen = m_dwInitSize;
m_dwIndex = 0 //初始化其他成员
}
template<class T_ELE>
Vector <T_ELE>::Vector(DWORD dwSize)::m_dwIncrement(5) //初始化类成员
{
m_pVector = new T_ELE[dwSize];//在堆中创建长度为dwSize个T_ELE对象
memset(m_pVector, 0, sizeof(Vector) * dwSize); //将创建的堆空间初始化
m_dwLen = dwSize;
m_dwIndex = 0 //初始化其他成员
}
template<class T_ELE>
Vector <T_ELE>::~Vector() //释放空间
{
delete[] m_pVector;
m_pVector = 0;
}
template<class T_ELE>
DWORD Vector <T_ELE>::push_back(T_ELE Element) //将元素存储到容器最后一个对象后
{
if(m_dwIndex >= m_dwLen)
{
expend(); //判断是否需要增容,如果需要则调用增容函数
}
memcpy(&m_pVector[m_dwIndex], &Element, sizeof(T_ELE)); //将元素存储到容器最后一个位置
m_dwIndex++;
return SUCCESS
}
template<class T_ELE>
BOOL Vector <T_ELE>:: expend()
{
DWORD dwTempLen = 0;
T_ELE* pTemp = NULL;
dwTempLen = m_dwLen + m_dwIncrement; //计算增加后的长度
pTemp = new T_ELE[dwTempLen]; //申请空间
memcpy(pTemp ,m_pVector, sizeof(T_ELE) * m_dwLen); //将数据复制到新空间
delete[] m_pVector;;
m_pVector = pTemp; //使类中指针指向新空间
pTemp = NULL
m_dwLen = dwTempLen; //修改其他成员
return TRUE;
}
template<class T_ELE>
DWORD Vector <T_ELE>:: insert(DWORD dwIndex, T_ELE Element)//在指定位置插入元素
{
if(dwIndex < 0 || dwIndex > m_dwIndex) //判断索引是否在合理区间
{
retrun INDEX_ERROR;
}
if(m_dwIndex >= m_dwLen) //判断是否需要增容,若需要则调用增容函数
{
expend();
}
for(int i = m_dwIndex; i > dwIndex; i--) //将dwIndex之后的元素后移
{
memcpy(&m_pVector[i], &m_pVector[i - 1], sizeof(T_ELE))
}
memcpy(&m_pVector[dwIndex], &Element, sizeof(T_ELE))//将Element元素复制到dwIndex位置
m_dwIndex++; //修改属性值
}
template<class T_ELE>
DWORD Vector <T_ELE>::at(DWORD dwIndex, T_ELE* pEle) //通过索引查元素
{
if(dwIndex < 0 || dwIndex >= m_dwIndex) //判断索引是否在合理区间
{
retrun INDEX_ERROR;
}
memcpy(pEle, &m_pVector[dwIndex], sizeof(T_ELE));
}
作业
以上述模板自行实现Vector
#include<Windows.h>
#include<iostream>
#define SUCCESS 1
#define ERROR 0
#define NEW_ERROR -1
#define INDEX_ERROR -2
template<typename T_ELE>
class Vector
{
public: //构造函数与析构函数
Vector();
Vector(DWORD dwSize);
~Vector();
public: //公开成员方法
DWORD at(DWORD dwIndex); //根据给定的索引得到元素
DWORD push_back(T_ELE element); //将element添加到最后一个位置
VOID pop_back(); //删除最后一个元素
DWORD insert(DWORD dwIndex, T_ELE pElement); //向指定位置插入element
DWORD erase(DWORD dwIndex); //删除指定元素
DWORD capacity(); //返回剩余空间
VOID clear(); //清除所有元素
BOOL empty(); //判断vector是否为空
DWORD size(); //返回vector有效元素的总个数
private: //私有成员方法
BOOL expand(); //vector扩容
private: //私有变量
DWORD m_dwIndex; //下一对象的索引
DWORD m_dwIncrement; //每次扩容的对象数量
DWORD m_dwLen; //当前容器对象数量
DWORD m_dwMaxLen; //当前容器可容纳最大对象数量
DWORD m_dwInitSize; //容器初始对象的数量
T_ELE* m_pVector; //容器指针
};
template<class T_ELE>
Vector <T_ELE>::Vector()
{
m_dwInitSize = 10;
m_dwIncrement = 5;//初始化类成员
//在堆中创建长度为m_dwInitSize个T_ELE对象
m_pVector = new T_ELE[m_dwInitSize];
//将创建的堆空间初始化
memset(m_pVector, 0, sizeof(T_ELE) * m_dwInitSize);
//初始化其他成员
m_dwIndex = 0;
m_dwMaxLen = m_dwInitSize;
m_dwLen = 0;
}
template<class T_ELE>
Vector <T_ELE>::Vector(DWORD dwSize)
{
m_dwInitSize = dwSize;//初始化类成员
//在堆中创建长度为dwSize个T_ELE对象
m_pVector = new T_ELE[dwSize];
//将创建的堆空间初始化
memset(m_pVector, 0, sizeof(T_ELE) * m_dwInitSize);
//初始化其他成员
m_dwIndex = 0;
m_dwMaxLen = m_dwInitSize;
m_dwLen = 0;
m_dwIncrement = 5;
}
template<class T_ELE>
Vector <T_ELE>::~Vector() //释放空间
{
delete[]m_pVector;
m_pVector = NULL;
std::cout << "该容器内存空间已释放" << std::endl;
}
template<class T_ELE>
DWORD Vector <T_ELE>::push_back(T_ELE Element) //将元素存储到容器最后一个对象后
{
//判断是否需要增容,如果需要则调用增容函数
if (m_dwIndex >= m_dwMaxLen && m_dwLen == m_dwMaxLen)
{
std::cout << "该容器大小不足,现开始扩容" << std::endl;
expand();
}
//将元素存储到容器最后一个位置
m_pVector[m_dwIndex] = Element;
m_dwIndex++;
m_dwLen++;
std::cout << "存储元素成功" << std::endl;
return SUCCESS;
}
template<class T_ELE>
BOOL Vector <T_ELE>::expand()
{
//计算增加后的长度
m_dwMaxLen += m_dwIncrement;
//申请空间
T_ELE* pTemp = new T_ELE[m_dwMaxLen];
//将数据复制到新空间
memset(pTemp, 0, sizeof(T_ELE) * m_dwMaxLen);
memcpy(pTemp, m_pVector, sizeof(T_ELE) * m_dwLen);
//使类中指针指向新空间
m_pVector = pTemp;
pTemp = NULL;
//修改其他成员
std::cout << "该容易扩容成功" << std::endl;
return SUCCESS;
}
template<class T_ELE>
DWORD Vector <T_ELE>::insert(DWORD dwIndex, T_ELE Element)//在指定位置插入元素
{
//判断索引是否在合理区间
if (dwIndex < 0)
{
std::cout << "该指定位置有误,请重新输入" << std::endl;
return INDEX_ERROR;
}
else if (dwIndex == m_dwIndex)
{
push_back(Element);
return TRUE;
}
else
{
//判断是否需要增容,若需要则调用增容函数
while (m_dwLen >= m_dwMaxLen)
{
expand();
}
//将dwIndex之后的元素后移
for (DWORD x = m_dwIndex; x > dwIndex; x--)
{
m_pVector[x] = m_pVector[x - 1];
}
//将Element元素复制到dwIndex位置
m_pVector[dwIndex] = Element;
//修改属性值
m_dwIndex++;
m_dwLen++;
std::cout << "元素插入成功" << std::endl;
}
}
template<class T_ELE>
DWORD Vector <T_ELE>::at(DWORD dwIndex) //通过索引查元素
{
//判断索引是否在合理区间
if (dwIndex < 0 || dwIndex > m_dwMaxLen)
{
std::cout << "索引输入错误" << std::endl;
return ERROR;
}
else
{
std::cout << "该指定位置的值为" << m_pVector[dwIndex] << std::endl;
return m_pVector[dwIndex];
}
}
template<class T_ELE>
VOID Vector <T_ELE>::pop_back()
{
DWORD LastNumber = m_dwLen - 1;
std::cout << "要删除的元素是" << m_pVector[LastNumber] << std::endl;
m_pVector[LastNumber] = 0;
m_dwLen--;
m_dwIndex--;
std::cout << "删除元素成功" << std::endl;
}
template<class T_ELE>
DWORD Vector <T_ELE>::erase(DWORD dwIndex)
{
if (dwIndex < 0 || dwIndex >= m_dwLen)
{
std::cout << "索引输入错误" << std::endl;
return ERROR;
}
else
{
std::cout << "要删除的元素是" << m_pVector[dwIndex] << std::endl;
m_pVector[dwIndex] = 0;
}
for (DWORD i = dwIndex; i < m_dwLen - 1; i++)
{
m_pVector[i] = m_pVector[i + 1];
}
m_pVector[m_dwLen - 1] = 0;
m_dwLen--;
m_dwIndex--;
std::cout << "删除元素成功" << std::endl;
}
template<class T_ELE>
DWORD Vector <T_ELE>::capacity()
{
std::cout << "该容器剩余空间为" << m_dwMaxLen - m_dwLen << std::endl;
return m_dwMaxLen - m_dwLen;
}
template<class T_ELE>
DWORD Vector <T_ELE>::size() //返回有效元素个数
{
std::cout << "该容器中有效元素个数为" << m_dwLen << std::endl;
return m_dwLen;
}
template<class T_ELE>
VOID Vector<T_ELE>::clear()
{
for (DWORD i = 0; i < m_dwLen; i++)
{
m_pVector[i] = 0;
}
std::cout << "所有元素已经清空" << std::endl;
m_dwLen = 0;
m_dwIndex = 0;
}
template<class T_ELE>
BOOL Vector<T_ELE>::empty()
{
if (m_dwLen == 0)
{
std::cout << "该Vector已空" << std::endl;
return TRUE;
}
else
{
std::cout << "该Vector不空" << std::endl;
return ERROR;
}
}
int main()
{
return 0;
}
该Vector经本人测试,没有毛病