顺序表Vector

程序中会使用数据结构;例如:顺序表、链表、二叉树;
数据结构在底层中本质上只有两种:数据之间挨着和不挨着;
 
1.关于Vector
    1】本质就是一个数组            
    2】可以动态扩充容量            
    3】支持下标方法,查询性能好            
    4】新增数据和删除数据较差   
        比如在A和B之间插入一个元素,B后面的所有数据都要后移
 
2.实现Vector
ArrayList.h
#ifndef ARRYALIST_H
#define ARRYALIST_H
 
#define VSUCCESS                        1 // 成功        
#define VERROR                         -1 // 失败        
#define MALLOC_ERROR             -2 // 申请内存失败        
#define INDEX_ERROR              -3 // 错误的索引号
 
#include "stdio.h"
#include <stdlib.h>
#include <windows.h>
    
template <class T_ELE>                                            
class Vector                                            
{                                            
public:                                                                
    Vector();
    Vector(DWORD dwSize);                                        
    ~Vector();                                        
public:                                            
    DWORD    at(DWORD dwIndex,OUT T_ELE* pEle);                    //根据给定的索引得到元素                
    DWORD    push_back(T_ELE Element);                        //将元素存储到容器最后一个位置                
    VOID    pop_back();                    //删除最后一个元素                
    DWORD    insert(DWORD dwIndex, T_ELE Element);                    //向指定位置新增一个元素                
    DWORD    capacity();                    //返回在不增容的情况下,还能存储多少元素                
    VOID    clear();                    //清空所有元素                
    BOOL    empty();                    //判断Vector是否为空 返回true时为空                
    VOID    erase(DWORD dwIndex);                    //删除指定元素                
    DWORD    size();                    //返回Vector元素数量的大小                
private:                                            
    BOOL    expand();                                    
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)                                            
{                                            
    //1.创建长度为m_dwInitSize个T_ELE对象
    m_pVector = new T_ELE[m_dwInitSize];
                                            
    //2.将新创建的空间初始化                                        
    memset(m_pVector, 0, sizeof(T_ELE)*m_dwInitSize);
    
    //3.设置其他值
    m_dwIndex = 0;
    m_dwLen = m_dwInitSize;
}    
 
//************有参构造*************                                        
template <class T_ELE>                                            
Vector<T_ELE>::Vector(DWORD dwSize)                                            
:m_dwIncrement(5)                                            
{                                            
    //1.创建长度为dwSize个T_ELE对象    
    m_pVector = new T_ELE[dwSize];
    if(!m_pVector){
        return;
    }
                                            
    //2.将新创建的空间初始化                                        
    memset(m_pVector, 0, sizeof(T_ELE)*dwSize);
 
 
    //3.设置其他值    
    m_dwIndex = 0;
    m_dwLen = dwSize;
    
}    
 
//************析构函数*************                                        
template <class T_ELE>                                            
Vector<T_ELE>::~Vector()                                            
{                                            
    //释放空间 delete[]    
    delete[] m_pVector;
                                        
                                            
}                                            
 
//************扩容*************                                                
template <class T_ELE>                                            
BOOL Vector<T_ELE>::expand()                                            
{                                            
    // 1. 计算增加后的长度                                        
    DWORD size = m_dwLen + m_dwIncrement;                                        
    printf("数组容量%d不够,扩容为%d\n", m_dwLen, size);                                        
    // 2. 申请空间                                        
    T_ELE* newArr = new T_ELE[size];
    if(!newArr){
        return FALSE;
    }
                                            
    // 3. 将数据复制到新的空间
    memset(newArr, 0, sizeof(T_ELE)*size);
    memcpy(newArr, m_pVector, sizeof(T_ELE)*m_dwLen);                                        
                                            
    // 4. 释放原来空间                                        
    delete[] m_pVector;
    m_pVector = newArr;
    newArr = NULL;
                                            
    // 5. 为各种属性赋值                                        
    m_dwLen = size;
 
 
    return TRUE;
}                                            
 
//************末尾添加*************                                                
template <class T_ELE>                                            
DWORD  Vector<T_ELE>::push_back(T_ELE Element)                                            
{                                            
    //1.判断是否需要增容,如果需要就调用增容的函数
    if(m_dwIndex >= m_dwLen){
        expand();    
    }
                                            
    //2.将新的元素复制到容器的最后一个位置
    m_pVector[m_dwIndex] = Element;
                                            
    //3.修改属性值                                        
    m_dwIndex++;
    return VSUCCESS;
}                                            
 
//************中间插入*************                                                
template <class T_ELE>                                            
DWORD  Vector<T_ELE>::insert(DWORD dwIndex, T_ELE Element)                                            
{                                            
    //1.判断是否需要增容,如果需要就调用增容的函数                                        
    if(m_dwIndex >= m_dwLen){
        expand();    
    }                                        
                                            
    //2.判断索引是否在合理区间                                        
    if(dwIndex<0 || dwIndex>m_dwIndex){
        return INDEX_ERROR;
    }                                        
                                            
    //3.将dwIndex只后的元素后移                                        
    for(int i=m_dwIndex;i>dwIndex;i--){
        memcpy(m_pVector+i, m_pVector+i-1, sizeof(T_ELE));    
    }                                        
                                            
    //4.将Element元素复制到dwIndex位置                                        
    memcpy(m_pVector+dwIndex, &Element, sizeof(T_ELE));
                                            
    //5.修改属性值
    m_dwIndex++;
    return VSUCCESS;
}    
 
//************下标获取*************                                            
template <class T_ELE>                                            
DWORD Vector<T_ELE>::at(DWORD dwIndex,T_ELE* pEle)                                            
{                                            
    //判断索引是否在合理区间                                        
    if(dwIndex<0 || dwIndex>=m_dwIndex){
        return INDEX_ERROR;
    }                                        
                                            
    //将dwIndex的值复制到pEle指定的内存                                        
    memcpy(pEle, m_pVector+dwIndex, sizeof(T_ELE));
    return VSUCCESS;
}                                            
 
//********末尾删除***********
template <class T_ELE>                                            
VOID Vector<T_ELE>::pop_back(){
    //判断是否还有
    if(m_dwLen <=0){
        printf("一个元素都没有了\n");
        return;
    }
    //删除
    m_dwIndex--;
    memset(m_pVector+m_dwIndex, 0, sizeof(T_ELE));
}    
 
//********不增容剩余容量********
template <class T_ELE>
DWORD Vector<T_ELE>::capacity(){
    return m_dwLen - m_dwIndex;
}                                    
    
//*********清空容器*******
template <class T_ELE>
VOID Vector<T_ELE>::clear(){
    memset(m_pVector, 0, sizeof(T_ELE)*(m_dwIndex + 1));
    //修改属性值
    m_dwIndex = 0;
}
 
//**********判断容器是否为空******
template <class T_ELE>
BOOL Vector<T_ELE>::empty(){
    if(m_pVector){
        return TRUE;
    }else{
        return FALSE;
    }
}                                
 
//*********删除指定元素********
template <class T_ELE>
VOID Vector<T_ELE>::erase(DWORD dwIndex){
    //判断下标是否在有效区间
    if(dwIndex<0 || dwIndex >m_dwIndex){
        printf("下标越界了\n");
        return;
    }
    //删除
    for(int i=dwIndex;i<m_dwIndex;i++){
        memcpy(m_pVector+i,m_pVector+i+1, sizeof(T_ELE));     
    }
    m_dwIndex--;
    memset(m_pVector+m_dwIndex, 0, sizeof(T_ELE));
 
}
 
//********返回元素数量*******
template <class T_ELE>
DWORD Vector<T_ELE>::size(){
    return m_dwIndex;
}
 
#endif

    

测试:
#include "ArrayList.h"
 
template <class T_ELE>
void printVector(Vector<T_ELE>* list){
    for(int i=0;i<list->size();i++){
        T_ELE k;
        list->at(i,&k);
        printf("%d\t",k);
    }
    printf("\n");
}
 
void main(){
    Vector<int>* list = new Vector<int>(5);
 
    list->push_back(1);
    list->push_back(2);
    list->push_back(3);
    list->push_back(4);
    printVector(list);
    printf("元素个数:%d,容量还剩%d\n",list->size(),list->capacity());
    
    list->insert(2,12);
    printVector(list);
    printf("元素个数:%d,容量还剩%d\n",list->size(),list->capacity());
 
    list->push_back(5);
    list->push_back(6);
    list->push_back(7);
    printVector(list);
    printf("元素个数:%d,容量还剩%d\n",list->size(),list->capacity());
 
    list->pop_back();
    list->erase(0);
    printVector(list);
    printf("元素个数:%d,容量还剩%d\n",list->size(),list->capacity());
 
    list->clear();
    printVector(list);
    printf("元素个数:%d,容量还剩%d\n",list->size(),list->capacity());
    
    getchar();
}
结果:
 
遇到的坑:
    本来想将vector的头文件和实现分开的,结果分开后编译出错,说头文件的函数没实现;
    可能是用了模板的原因,也不清楚,浪费时间在不太重要的地方不划算,总之不分开就好了;
 
 
 
 
posted @ 2019-11-29 11:21  L丶银甲闪闪  阅读(373)  评论(0)    收藏  举报