数组描述线性表(C++实现)

线性表也称有序表,其每一个实例都是元素的一个有序集合

抽象类linearList

一个抽象类包含没有实现代码的成员函数,这样的成员函数称为纯虚函数,用数字0作为初始值来说明

template<class T>
class linearList {
public:
    virtual ~linearList() {};
    virtual bool empty() const = 0; // 是否为空
    virtual int size() const = 0; // 元素个数
    virtual T& get(int theIndex) const = 0; // 获取索引为theIndex的元素
    virtual int indexOf(const T &theElement) const = 0; // 返回元素第一次出现时的索引
    virtual void earse(int theIndex) = 0; // 删除索引为theIndex的元素
    virtual void insert(int theIndex,const T &theElement) = 0; // theElement插入线性表中索引为theIndex的位置上
    virtual void output(std::ostream& out) const = 0; // 输出流
};

此处定义了线性表的抽象类,及其一系列纯虚函数

数组描述

这里用一维数组来存储线性表元素

变长一维数组

定义如下函数可以改变数组的长度,首先建立一个具有新长度的数组,然后将数组a的元素复制到这个新数组,最后改变数组a的值,使其能够引用新数组

template<class T>
void changeLength1d(T* &a,int oldLength,int newLength) {
    if (newLength < 0) {
        throw illegalParameterValue("new length must be >= 0");
    }
    T* temp = new T[newLength];
    int number = min(oldLength,newLength);
    copy(a,a+number,temp);
    delete[] a;
    a = temp;
}

arrayList类

定义一个C++抽象类linearList的派生类arrayList,因为arrayList是一个具体类,所以它必须实现抽象类linearList的所有方法,同时还包含基类没有声明的方法

template<class T>
class arrayList : public linearList<T> {
public:
    arrayList(int initialCapacity = 10);
    arrayList(const arrayList<T>&);
    ~arrayList() { delete[] element; }

    bool empty() const { return listSize == 0; }
    int size() const { return listSize; }
    T& get(int theIndex) const;
    int indexOf(const T& theElement) const;
    void earse(int theIndex);
    void insert(int theIndex,const T& theElement);
    void output(std::ostream& out) const;
    int capacity() const { return arrayLength; }
protected:
    void checkIndex(int theIndex) const;
    T *element;
    int arrayLength;
    int listSize;
};

如下定义类构造函数和复制构造函数

template<class T>
arrayList<T>::arrayList(int initialCapacity) {
    if (initialCapacity < 1) {
        ostringstream s;
        s << "Initial capacity = " << initialCapacity << " Must be > 0";
        throw illegalParameterValue(s.str());
    }
    arrayLength = initialCapacity;
    element = new T[arrayLength];
    listSize = 0;
}

template<class T>
arrayList<T>::arrayList(const arrayList<T>& theList) {
    arrayLength = theList.arrayLength;
    listSize = theList.listSize;
    element = new T[arrayLength];
    copy(theList.element,theList.element+listSize,element);
}

类构造函数中,创建了一个长度为initialCapacity的数组,默认值为10,并初始化arrayLength和listSize

复制构造函数中是复制一个对象,当一个对象传值给一个函数,或者一个函数返回一个对象时,都要调用复制构造函数,利用了STL的copy函数

基本方法

如下定义了arrayList类基本的方法:

template<class T>
void arrayList<T>::checkIndex(int theIndex) const {
    if (theIndex < 0 || theIndex >= listSize) {
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw illegalIndex(s.str());
    }
}

template<class T>
T& arrayList<T>::get(int theIndex) const {
    checkIndex(theIndex);
    return element[theIndex];
}

template<class T>
int arrayList<T>::indexOf(const T &theElement) const {
    int theIndex = (int) (find(element,element+listSize,theElement)-element);
    if (theIndex == listSize) {
        return -1;
    } else {
        return theIndex;
    }
}

checkIndex检查索引是否在有效范围内,get获取索引对应的元素,indexOf返回指定元素第一次出现的索引

删除元素

利用copy将索引从theIndex+1及其向后的元素向左移动一个位置,然后将listSize减1

template<class T>
void arrayList<T>::earse(int theIndex) {
    checkIndex(theIndex);
    copy(element+theIndex+1,element+listSize,element+theIndex);
    element[--listSize].~T();
}

插入元素

要把线性表中索引为theIndex的位置上插入一个新元素,首先将索引从theIndex到listSize-1的元素向右移动一个位置(调用copy_backward),然后将新元素插入指定位置:

template<class T>
void arrayList<T>::insert(int theIndex, const T &theElement) {
    if (theIndex < 0 || theIndex > listSize) {
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw illegalParameterValue(s.str());
    }
    if (listSize == arrayLength) {
        changeLength1d(element,arrayLength,2*arrayLength);
        arrayLength *= 2;
    }
    copy_backward(element+theIndex,element+listSize,element+listSize+1);
    element[theIndex] = theElement;
    listSize++;
}

输出函数

定义输出函数(将线性表插入输出流),并重载流插入符<<

template<class T>
void arrayList<T>::output(ostream &out) const {
    copy(element,element+listSize,ostreambuf_iterator<T>(cout," "));
}

template <class T>
ostream& operator<<(ostream &out,const arrayList<T> &x) {
    x.output(out);
    return out;
}

迭代器

如下定义一个C++类iterator,是类arrayList的双向迭代器,这个迭代器是类arrayList的公有成员,此外为类arrayList增加两个公有的方法begin()和end()

class iterator;
iterator begin() { return iterator(element); }
iterator end() { return iterator(element+listSize); }

迭代器实现:

template<class T>
class iterator {
public:
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef T value_type;
    typedef ptrdiff_t difference_type;
    typedef T *pointer;
    typedef T &reference;

    iterator(T *thePosition = 0) { position = thePosition; }
    T& operator*() const { return *position; }
    T* operator->() const { return &*position; }
    iterator& operator++() { ++position; return *this; }
    iterator& operator++(int) { iterator old = *this; ++position; return old; }
    iterator& operator--() { --position; return *this; }
    iterator& operator--(int) { iterator old = *this; --position; return old; }
    bool operator!=(const iterator right) const { return  position != right.position; }
    bool operator==(const iterator right) const { return position == right.position; }
protected:
    T *position;
};

原文链接: https://www.cnblogs.com/N3ptune/p/17043695.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    数组描述线性表(C++实现)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/311177

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 上午11:54
下一篇 2023年2月16日 上午11:54

相关推荐