动态顺序线性表

template<class T>
class NewVector {
public:
    NewVector();
    ~NewVector();
    bool push_front(T nData);  //添加到头部
    bool push_back(T nData);     //添加到尾部
    bool pop_back(T* pData = 0);   //删除最后一个元素
    bool pop_front(T* pData = 0); //删除头元素
    int  max_size();  //返回最大长度
    int&  operator[](int nIndex);  //重载运算符[]
    bool insert(int pos, T nData);    //从任意位置添加
    bool insert1(int pos,int n, T elem);  //在pos索引位置插入n个元素elem
    bool insert2(int pos,int beg,int end);//在pos位置插入线性表的beg到end的元素,不包括end
    int at(int idx);//返回索引为idx的元素
    bool erase(int pos, T* pData = 0);  //从任意位置删除
    bool remove(T elem); //删除指定数据
    bool empty();   //是否为空
    void clear();   //清空所有
    int findData(T elem);    //查找元素所在位置的下标 
    bool findIndex(int nIndex, T* pData=0);  //查找索引所对应的数据
    int size();   //获取当前元素个数
    bool setData(int nIndex, T elem);   //修改下标为nIndex的元素的值为nData
    void Print();//遍历打印
    bool extend();   //扩展空间
    bool reduce();//消减空间
private:
    T* m_headerPoint;       //头指针
    int m_max;      //当前最多存储元素个数
    int m_count;  //当前存储元素个数
};


template<class T>
NewVector<T>::NewVector() {
    m_max = 5;
    m_count = 0;
    m_headerPoint = new T[m_max] {};
}
template<class T>
NewVector<T>::~NewVector() {
    clear();
}
//添加到头部
template<class T>
bool NewVector<T>::push_front(T nData) {
    if (m_count == m_max)
    {
        extend();
    }
    for (int i = m_count; i > 0; i--)
    {
        m_headerPoint[i] = m_headerPoint[i - 1];
    }
    m_headerPoint[0] = nData;
    m_count++;
    return true;
}
//添加到尾部
template<class T>
bool NewVector<T>::push_back(T nData) {
    if (m_count == m_max) {
        if (!extend()) {
            return false;
        }
    }
    m_headerPoint[m_count++] = nData;
    return true;
}
//删除最后一个元素
template<class T>
bool NewVector<T>::pop_back(T* pData) {
    if (empty()) {
        return false;
    }
    if (pData) {
    *pData = m_headerPoint[m_count - 1];
    }
    m_count--;
    if (m_max - m_count > 5) {
        return reduce();
    }
    return true;
}
//删除头元素
template<class T>
bool NewVector<T>::pop_front(T* pData) {
    if (empty()) { return false; }
    for (int i = 0; i < m_count - 1; i++)//往前移动元素
    {
        m_headerPoint[i] = m_headerPoint[i + 1];
    }
    if (pData) {
        *pData = m_headerPoint[m_count - 1];
    }
    m_headerPoint[m_count - 1] = 0;
    m_count--;
    if (m_max - m_count > 5)
    {
        return reduce();
    }
    return true;
}
//返回最大长度
template<class T>
int  NewVector<T>::max_size() {
    return m_max;
}
//重载运算符[]
template<class T>
int&  NewVector<T>::operator[](int nIndex) {
    return m_headerPoint[nIndex];
}
//从任意位置添加
template<class T>
bool NewVector<T>::insert(int pos, T nData) {
    //如果不合法
    if (pos<0 || pos > m_count) {
        return false;
    }
    //如果满了
    if (m_count == m_max) {
        extend();
    }
    //如果头部插入
    if (pos == 0) {
        return push_front(nData);
    }
    //如果尾部插入
    else if (pos == m_count) {
        return push_back(nData);
    }
    else {
        for (int i = m_count; i > 0; i--) {
            m_headerPoint[i] = m_headerPoint[i - 1];
        }
        m_headerPoint[pos] = nData;
    }
    m_count++;
    return true;
}
//在pos索引位置插入n个元素elem
template<class T>
bool NewVector<T>::insert1(int pos, int n, T elem) {
    if (pos<0 || pos>m_count)
    {
        return false;
    }
    //空间不足扩容;
    if (m_max - m_count <= n)
    {
        extend();
    }
    //如果头部插入
    if (pos == 0) {
        for (int i = 0; i < n; i++) {
            push_front(elem);
        }
    }
    //如果尾部插入
    else if (pos == m_count) {
        for (int i = 0; i < n; i++) {
            push_back(elem);
        }
    }
    else {
        for (int i = (m_count + n - 1); i > (pos + n - 1); i--)
        {
            m_headerPoint[i] = m_headerPoint[i - n];
        }
        for (int i = pos; i < (pos + n); i++)
        {
            m_headerPoint[i] = elem;
        }
    }
    m_count += n;
    return true;
}
//在pos位置插入线性表中的beg到end的元素,不包括end
template<class T>
bool NewVector<T>::insert2(int pos, int beg, int end) {
    if (pos<0 || pos>m_count)
    {
        return false;
    }
    //空间不足扩容;
    if (m_max - m_count <= (end - beg - 1))
    {
        extend();
    }
    //如果头部插入
    if (pos == 0) {
        for (int i = end - 1; i >= beg; i--) {
            push_front(m_headerPoint[i]);
        }
    }
    //如果尾部插入
    else if (pos == m_count) {
        for (int i = beg; i < end; i++) {
            push_front(m_headerPoint[i]);
        }
    }
    else {
        for (int i = (m_count + (end - beg) - 1); i > (pos + (end - beg) - 1); i--)
        {
            m_headerPoint[i] = m_headerPoint[i - (end - beg )];
        }
        for (int i = pos, j = beg; i < (pos + (end - beg)); i++, j++)
        {
            m_headerPoint[i] = m_headerPoint[j];
        }
    }
    m_count += (end - beg);
    return true;
}
//返回索引为idx的元素
template<class T>
int NewVector<T>::at(int idx) {
    if (idx<0 || idx>m_count)
    {
        return -1;
    }
    else return m_headerPoint[idx];
}
//从任意位置删除
template<class T>
bool NewVector<T>::erase(int pos, T* pData) {
    //索引是不是无效
    if (pos<0 || pos>m_count) {
        return false;
    }
    //是不是为空
    if (empty()) { return false; }
    //是不是头部
    if (pos == 0) {
        return pop_front(pData);
    }
    //是不是尾部
    if (pos == m_count-1) {
        return pop_back(pData);
    }
    if(pData){
    *pData = m_headerPoint[pos];
    }
    //移动元素
    for (int i = pos; i < m_count; i++)
    {
        m_headerPoint[i] = m_headerPoint[i + 1];
    }
    m_count--;
    if (m_max - m_count > 5)
    {
        return reduce();
    }
    return true;
}
//删除指定数据
template<class T>
bool NewVector<T>::remove(T elem) {
    for (int i = 0; i < m_count; i++)
    {
        if (m_headerPoint[i] == elem)
        {
            //找到后根据下标删除数据
            return erase(i);
        }
    }
    return false;
}
//是否为空
template<class T>
bool NewVector<T>::empty() {
    if (m_count == 0) { return true; }
    return false;
}
//清空所有
template<class T>
void NewVector<T>::clear() {
    if (m_headerPoint)
    {
        delete[] m_headerPoint;
        m_headerPoint = nullptr;
        m_count = 0;
    }
}
//查找元素所在位置的下标 
template<class T>
int NewVector<T>::findData(T elem) {
    for (int i = 0; i < m_count;i++) {
        if (m_headerPoint[i] == elem)
        {
            return i;
        }
    }
    return -1;
}
//查找索引所对应的数据
template<class T>
bool NewVector<T>::findIndex(int nIndex, T* pData) {
    if (nIndex < 0 || nIndex >= m_count)
    {
        return false;
    }
    for (int i = 0; i < m_count; i++) {
        if (m_headerPoint[nIndex])
        {
            *pData = m_headerPoint[nIndex];
            return true;
        }
    }
    return false;
}
//获取当前元素个数
template<class T>
int NewVector<T>::size() {
    return m_count;
}
//修改下标为nIndex的元素的值为nData
template<class T>
bool NewVector<T>::setData(int nIndex, T elem) {
    if (nIndex < 0 || nIndex >= m_count)
    {
        return false;
    }
    m_headerPoint[nIndex] = elem;
    return true;
}
//遍历打印
template<class T>
void NewVector<T>::Print() {
    for (int i = 0; i < m_count; i++) {
        cout << m_headerPoint[i]<<" ";
    }
    cout << endl;
}
//扩展空间
template<class T>
bool NewVector<T>::extend() {
    int* p = new T[m_max + 5]{};
    //申请失败
    if (!p) { return false; }
    for (int i = 0; i < m_count; i++) {
        p[i] = m_headerPoint[i];
    }
    delete m_headerPoint;
    m_headerPoint = p;
    m_max += 5;
    return true;
}
//消减空间
template<class T>
bool NewVector<T>::reduce() {
    int* p = new T[m_max - 5]{};
    //申请空间失败
    if (!p) { return false; }
    if (m_max - m_count < 5) return false;//消减失败
    for (int i = 0; i < m_count; i++) {
        p[i] = m_headerPoint[i];
    }
    delete m_headerPoint;
    m_headerPoint = p;
    m_max -= 5;
    return true;
}



int main()
{
    NewVector<int> newvector;
    printf("先尾部插入12345\n");
    newvector.push_back(1);
    newvector.push_back(2);
    newvector.push_back(3);
    newvector.push_back(4);
    newvector.push_back(5);
    printf("在1的位置插入6\n");
    newvector.insert(1, 6);
    printf("操作后为:\n");
    newvector.Print();
    printf("现在最大容量为:%d\n", newvector.max_size());
    int nData;
    printf("头部删除一个元素\n");
    newvector.pop_front(&nData);
    printf("操作后为:\n");
    newvector.Print();
    printf("尾部删除一个元素\n");
    newvector.pop_back(&nData);
    printf("操作后为:\n");
    newvector.Print();
    printf("在2的位置插入两个8\n");
    newvector.insert1(2, 2, 8);
    printf("操作后为:\n");
    newvector.Print();
    printf("在2的位置插入原表中2-4的元素,不包括4\n");
    newvector.insert2(2, 2, 4);
    printf("操作后为:\n");
    newvector.Print();
    printf("删除一个元素8\n");
    newvector.remove(8);
    printf("操作后为:\n");
    newvector.Print();
    printf("删除下标为3的元素\n");
    newvector.erase(3, &nData);
    printf("操作后为:\n");
    newvector.Print();
    if (newvector.findIndex(1, &nData)) {
        printf("找到索引为1的元素\n");
    }
    if (newvector.findData(8)) {
        printf("找到元素8\n");
    }
    printf("现在最大容量为:%d\n", newvector.max_size());
    newvector.extend();
    printf("主动扩容一次操作后:\n");
    newvector.Print();
    printf("现在最大容量为:%d\n", newvector.max_size());
    printf("进行一次尾部删除操作\n");
    newvector.pop_back(&nData);
    printf("然后自动判断要不要消减空间大小\n");
    printf("现在最大容量为:%d\n", newvector.max_size());
    system("pause");
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容