C++ Vector线性表的数组实现

STL中的Vector容器就是线性表的数组实现,因为最近学习数据结构,于是手工实现了一遍数组描述的线性表

// 2020/02/14 Tealer.Guo

#include <algorithm> // copy(), find(), copy_backward()
#include <iostream>
#include <iterator> // ostream_iterator<>

// 线性表
// ADT 抽象数据类型
// 纯虚函数
template<typename T>
class linearList {
    public:
        virtual ~linearList() {};
        virtual bool empty() const = 0; // 当线性表为空时,返回0
        virtual int size() const = 0; // 返回线性表的元素个数
        virtual T& get(int this_index) const = 0; // 返回具有this_index索引的元素
        virtual int indexOf(const T& this_elem) const = 0; // 返回元素的索引
        virtual void erase(int this_index) = 0; // 删除该索引的元素
        virtual void insert(int this_index, const T& this_elem) = 0; // 插入索引和元素
        virtual void output(std::ostream& out) const = 0; // 输出线性表      
};

// arrayList 线性表数组描述
// 继承ADT
template<typename T>
class arrayList : public linearList<T> {
    public:
        arrayList(int init_capacity = 10); // 构造函数
        arrayList(const arrayList<T>&); // 复制构造函数
        ~arrayList() { delete [] elements; } // 析构函数

        // ADT方法
        bool empty() const { return list_size == 0; } // 当线性表为空时,返回0
        int size() const { return list_size; } // 返回线性表的元素个数
        T& get(int this_index) const; // 返回具有this_index索引的元素
        int indexOf(const T& this_elem) const; // 返回元素的索引
        void erase(int this_index); // 删除该索引的元素
        void insert(int this_index, const T& this_elem); // 插入索引和元素
        void output(std::ostream& out) const; // 输出线性表 

        // 其它方法
        int capacity() const { return array_length; } // 返回当前表大小(长度)
    protected:
        // 访问控制,可以被子类访问
        void checkIndex(int this_index) const; // 检查索引,索引无效就抛出异常
        T* elements; // 指向表第一个元素地址
        int array_length; // 表总长
        int list_size; // 当前元素长度
};

// 方法实现
template<typename T>
arrayList<T>::arrayList(int init_capacity) {
    // 构造函数
    if(init_capacity < 1) {
        std::cerr << "The initial capacity mush >= 1 !";
        exit(1);
    }
    array_length = init_capacity;
    elements = new T[array_length]; // 建立表
    list_size = 0;
}

template<typename T>
arrayList<T>::arrayList(const arrayList<T>& this_arrayList) {
    // 复制构造函数
    array_length = this_arrayList.array_length;
    list_size = this_arrayList.list_size;
    elements = new T[array_length]; // 建立新的表
    std::copy(this_arrayList.elements, this_arrayList.elements + list_size, elements); // 复制表 copy(起始地址,终止地址,复制目标)
}

template<typename T>
void arrayList<T>::checkIndex(int this_index) const {
    // 索引检查
    if(this_index < 0 || this_index > list_size) {
        std::cerr << "Out of index !";
    }
}

template <typename T>
T& arrayList<T>::get(int this_index) const {
    // 根据索引取得元素
    checkIndex(this_index); // 检查索引
    return elements[this_index];
}

template<typename T>
int arrayList<T>::indexOf(const T& this_elem) const {
    // 根据元素取得索引
    int this_index = (int)(std::find(elements, elements + list_size, this_elem) - elements); // find(起始地址,终止地址,要找的元素)

    if(this_index == (list_size)) {
        return -1; // 没有找到
    } else {
        return this_index;
    }
}

template<typename T>
void arrayList<T>::erase(int this_index) {
    // 删除元素
    checkIndex(this_index); // 检查索引

    // 移动元素
    std::copy(elements + this_index + 1, elements + list_size, elements + this_index);

    // 调用析构函数
    elements[list_size--].~T(); // 显示调用具体类型自己的析构函数例如~int()
    // elements[list_size-=1].~T(); 等于 elements[list_size].~T();list_size -= 1;
    // elements[list_size].~T();
    // list_size -= 1; // 长度-1
}

template<typename T>
void arrayList<T>::insert(int this_index, const T& this_elem) {
    // 插入元素
    checkIndex(this_index); // 检查索引

    if(list_size == array_length) {
        // 表已满
        T* temp = new T[array_length * 2]; // 创建一个两倍大的新表
        std::copy(elements, elements + list_size, temp); // 将旧表复制到新表
        delete [] elements;
        elements = temp;
    }

    // 将元素向后移动一位
    std::copy_backward(elements + this_index, elements + list_size, elements + list_size + 1);
    elements[this_index] = this_elem; // 写入表
    list_size += 1; // 长度+1
}

template<typename T>
void arrayList<T>::output(std::ostream& out) const {
    // 输出表
    std::copy(elements, elements + list_size, std::ostream_iterator<T>(out, " "));
}

template<typename T>
std::ostream& operator<<(std::ostream& out, arrayList<T>& this_elem) {
    // 重载<<
    this_elem.output(out);
    return out;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值