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

抽象类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. K8S中Pod概念

    一.资源限制 Pod 是 kubernetes 中最小的资源管理组件,Pod 也是最小化运行容器化应用的资源对象.一个 Pod 代表着集群中运行的一个进程.kubernetes 中其他大多数组件都是围 ...

  2. PHP如何在两个大文件中找出相同的记录?

    1.引言 给定a,b两个文件, 分别有x,y行数据, 其中(x, y均大于10亿), 机器内存限制100M,该如何找出其中相同的记录? 2.思路 处理该问题的困难主要是无法将这海量数据一次性读进内存中 ...

  3. 基于C语言的小学生四则运算出题器

    一.实验目的以及项目来源: 目的: 1.帮助老师产出随机的海量四则运算符的运算题目. 2.每次题目的产出均为随机,增强同学的四则运算能力. 项目来源: 项目来源于软件开发与创新课程的结对编程,对100 ...

  4. Matlab %壹

    第一章 基本操作 MATLAB as A Calculator operators: + - * / ^ 顺序: Parenthesis () Power (^) *or/ +or- 特殊的: sqr ...

  5. 虚拟机文件丢失,虚拟机无法启动,通过xx-flat.vmdk和xx-delta.vmdk恢复虚拟机

    突然掉电,导致虚拟机文件夹里面的文件丢失,只剩余-flat.vmdk和-delta.vmdk文件,其他文件全部丢失,文件格式原本为"文件"格式.新建虚拟机无法直接使用此文件夹里面的 ...

  6. PC端,知乎在不想登录的情况下一打开就弹出登录框的无痛解决办法

    基于chrome浏览器 第一步: chrome://settings/content/javascript 第二步:添加禁用项 [*.]zhihu.com

  7. Docker安装:Centos7.6安装Docker

    Docker03:Centos7.6安装Docker 前提条件 内核版本 更新yum 包 卸载旧版本(如果安装过旧版本的话) 安装依赖包 设置yum源(阿里云源) 更新缓存 安装容器 启动并加入开机启 ...

  8. k8s集群角色管理

    查看集群各节点角色: [root@k8s-master-2 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master-1 Ready ...

  9. 解决Selenium元素拖拽不生效Bug

    转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/e8aa6c6f.html 你好,我是测试蔡坨坨. 前几天在使用Selenium进行元素拖拽操作时,发现Selenium自带的 ...

  10. 这篇文章汇聚33个BUG!来挑战一下,看看你能找出来几个?

    你好呀,我是歪歪. 前几天看到"Qunar技术沙龙"公众号推送了一篇关于他们举办了一场"Code Review大赛"的文章. 看到 Code Review 我很 ...