数据结构与算法(二)Vector

数据结构

通过一些特定的数据结构,我们可以高效的存储大量数据

从底层来讲,数据结构其实分为两种:顺序和链式,也就是数据成员是否互相挨着

接下来我们来讲述Vector

Vector

Vector的特点:

  1. 本质就是一个数组
  2. 可以动态扩充容量
  3. 支持下标方法,这也意味着该数据结构存储的数据是连续的,查询性能好
  4. 新增数据和删除数据的性能 较差

现在我们来实现该数据结构

如下是通过模板们实现的该数据结构部分功能,我们可以根据该模板进行下一步的实现与优化

#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经本人测试,没有毛病

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值