数据结构c++版(1)-线性表(数组表示)


参考资料《数据结构,算法与应用》c++版。

1.简介

线性表有多种表示方法,其中一种是利用c++中的内置数组来实现的,此种方法也称为静态存储。如何确定线性表的第0个元素和第n-1个(最后一个)元素在数组的位置呢?我们需要一种映射,或者说一个公式来快速地定位元素在数组中的位置。
一种常见的方法就是:location(i) = i ,线性表的起始位置和数组的起始位置正好重合。正因为有这种映射,可以让我们很快的得到对应索引的元素。
为了简化起见,这里不包含错误提示,假设用户能够正确的使用以及索引元素,不会出现越界这类操作。

2. 线性表的数组表示

以下为线性表的数组实现类:
先看私有成员变量,一个代表用来储存线性表的数组,剩下两个分别表示数组和线性表的大小。
再看成员函数,构造函数(生成一个初始容量为10的数组),复制构造函数以及析构函数。
其余的便是标准的ADT函数。

// Definition of arrayList
template <typename T>
class arrayList {
public:
    arrayList(int initialCapacity = 10);  // ctor
    arrayList(const arrayList<T>&);       // copy ctor
    ~arrayList() { delete[] element; }    // dtor

    bool empty() const { return listSize == 0; }
    int size() const { return listSize; }
    T& get(int theIndex) const;
    int indexOf(const T& theElement) const;
    void erase(int theIndex);
    void insert(int theIndex, const T& theElement);
    int capacity() const { return arrayLength; }

private:
    T* element;       // array to store list
    int arrayLength;  // capacity of array
    int listSize;     // number of element in list
};

3. 线性表的数组实现

// ctor
template <typename T>
arrayList<T>::arrayList(int initialCapacity = 10)
    : element(new T[initialCapacity]),
      arrayLength(initialCapacity),
      listSize(0) {}

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

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

template <typename T>
int arrayList<T>::indexOf(const T& theElement) const {
    // return the index of first occurence of theElement
    // return -1 if theElement is not in list
    for (int i = 0; i < listSize; i++) {
        if (theElement == element[i])
            return i;
        else
            return -1;
    }
}

template <typename T>
void arrayList<T>::erase(int theIndex) {
    // left shift one element: shift element[index+1,listSize) to
    // element[index,listSize-1), and delete last element element[listSize-1]
    std::copy(element + theIndex + 1, element + listSize, element + theIndex);
    element[--listSize].~T();
}

template <typename T>
void arrayList<T>::insert(int theIndex, const T& theElement) {
    // if the arrayList is full, double the arrayLength
    if (listSize == arrayLength) {
        changeLength1D(element, arrayLength, 2 * arrayLength);
        arrayLength *= 2;
    }
    // right shift: element[index, listSize) -> element[index+1, listSize + 1)
    // backward copy
    std::copy_backward(element + theIndex, element + listSize,
                       element + listSize + 1);
    element[theIndex] = theElement;
    listSize++;
}

template <typename T>
void changeLength1D(T*& array, int oldLength, int newLength) {
    T* new_array = new T[newLength];
    int number = min(oldLength, newLength);
    std::copy(array, array + number, new_array);  // stl copy
    delete[] array;
    array = new_array;  // make old array become new array
}

4.注意事项

这里用了一些STL的算法,比如copy,copy_backward。

template<class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = *first;
    ++result; ++first;
  }
  return result;
}

template<class BidirectionalIterator1, class BidirectionalIterator2>
  BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
                                         BidirectionalIterator1 last,
                                         BidirectionalIterator2 result )
{
  while (last!=first) *(--result) = *(--last);
  return result;
}

参数first和last没什么好说的,代表着你想复制的元素的首尾地址(迭代器)。对于result,copy中代表的是目标的首元素地址,而copy_backward中代表的是目标的最后一位还要加一的地址(末尾哨兵)。
因为数组为静态储存,对于静态操作,比如查找,只需常数时间O(1)。而对于动态操作,比如插入,删除,则需要O(n)的时间。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值