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

抽象类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;
};

数组描述线性表(C++实现)的更多相关文章

  1. C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)

    经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1. 线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2. 采用的实现方式:一段地 ...

  2. [C++]使用vector描述线性表定义及基本操作

    #ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" ...

  3. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

  4. 线性表——顺序表的实现与讲解(C++描述)

    线性表 引言 新生安排体检,为了 便管理与统一数据,学校特地规定了排队的方式,即按照学号排队,谁在前谁在后,这都是规定好的,所以谁在谁不在,都是非常方便统计的,同学们就像被一条线(学号)联系起来了,这 ...

  5. javascript实现数据结构:线性表--简单示例及线性表的顺序表示和实现

    线性表(linear list)是最常用且最简单的一种数据结构.一个线性表是n个数据元素的有限序列.在稍复杂的线性表中,一个数据元素可以由若干个数据项(item)组成. 其中: 数据元素的个数n定义为 ...

  6. 数据结构与算法(C/C++版)【绪论/线性表】

    声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识  /// ...

  7. 线性表&顺序线性表

    第二章 线性表 参考文献:[数据结构(C语言版)].严蔚敏 本篇章仅为个人学习数据结构的笔记,不做任何用途. 2.1 线性结构的特点 (1). 存在唯一的一个被称为"第一个"的数据 ...

  8. java资料——线性表(转)

    线性表 线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表的逻辑结构简单, ...

  9. c语言数据结构学习心得——线性表

    线性表:具有相同数据类型的n(n>0)个数据元素的有限序列. 主要有顺序存储和链式存储. 顺序存储: 特点:地址连续,随机/存取,顺序存储. 建立:首地址/存储空间大小(数组),表长. 方式:静 ...

  10. 线性表结构的Java实现

    一.线性表的抽象数据类型表述 线性表的结构简单,长度允许动态增长或搜索:可以对线性表中的任何数据元素进行访问和查找:允许进行数据的插入和删除操作:求线性表中的指定数据的前驱和后继:合并线性表以及拆分线 ...

随机推荐

  1. EF调用sql语句

    1.连接数据库 2.在Dal进行调用sql语句 public List<UserInfo> PageShow(out int totalcount,out int totalpage, s ...

  2. 纯前端实现后端给数据进行文件导出——angular里面的使用

    interface dataList { cmd_cnt: number; risk_name: string; user_cnt: number; risk_type:string; } listO ...

  3. swagger 兼容 docker 转发 配置

    app.UseSwagger(c => { c.PreSerializeFilters.Add((swagger, httpReq) => { string swagger_index_u ...

  4. Centos 8 部署harbor 访问502

    部署过程不做多说, 部署完之后访问502, 以下可能只是一种情况, 有可能是其它情况导致的503 查看日志 core.log 提示访问数据库被拒绝 贴出解决方案:https://github.com/ ...

  5. 使用selemium被反爬解决方法

    使用selenium进行自动化的时候,如csdn登录时可能会遇到检测反爬,从而需要验证       1. 反爬 有时候,我们利用 Selenium 自动化爬取某些网站时,极有可能会遭遇反爬. 实际上, ...

  6. vue input有值但还是验证不通过

    验证失败原因: 因为input自动把输入的值转换为string类型,导致验证失败. 解决方案: 一. Input中的v-model改为v-model.number: 二.rules里面需要加type: ...

  7. C#截取字符串的方法

    #region 得到字符串的长度    /// <summary>    /// 得到字符串的长度    /// </summary>    /// <param nam ...

  8. unlua

    安装 复制 Plugins 目录到你的UE工程根目录. 重新启动你的UE工程 注意点 新建工程后,必须重新拷贝插件,重新编译.不能从老项目中拷贝,会崩溃~ 加载c++类和蓝图类 -- c++类 loc ...

  9. Hyperf安装

    转载网址: https://www.cnblogs.com/lyc94620/p/12821723.html

  10. Python学习笔记--文件的相关操作

    文件的读取操作 读操作 实现: read()--读完 read(10)--读取10个字节 readline()--将所有行并到一行输出 readlines()--一次读取一行 文件的关闭: 实现: 上 ...