数组描述线性表(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;
};
数组描述线性表(C++实现)的更多相关文章
- C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1. 线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2. 采用的实现方式:一段地 ...
- [C++]使用vector描述线性表定义及基本操作
#ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" ...
- 线性表之顺序存储结构(C语言动态数组实现)
线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...
- 线性表——顺序表的实现与讲解(C++描述)
线性表 引言 新生安排体检,为了 便管理与统一数据,学校特地规定了排队的方式,即按照学号排队,谁在前谁在后,这都是规定好的,所以谁在谁不在,都是非常方便统计的,同学们就像被一条线(学号)联系起来了,这 ...
- javascript实现数据结构:线性表--简单示例及线性表的顺序表示和实现
线性表(linear list)是最常用且最简单的一种数据结构.一个线性表是n个数据元素的有限序列.在稍复杂的线性表中,一个数据元素可以由若干个数据项(item)组成. 其中: 数据元素的个数n定义为 ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- 线性表&顺序线性表
第二章 线性表 参考文献:[数据结构(C语言版)].严蔚敏 本篇章仅为个人学习数据结构的笔记,不做任何用途. 2.1 线性结构的特点 (1). 存在唯一的一个被称为"第一个"的数据 ...
- java资料——线性表(转)
线性表 线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表的逻辑结构简单, ...
- c语言数据结构学习心得——线性表
线性表:具有相同数据类型的n(n>0)个数据元素的有限序列. 主要有顺序存储和链式存储. 顺序存储: 特点:地址连续,随机/存取,顺序存储. 建立:首地址/存储空间大小(数组),表长. 方式:静 ...
- 线性表结构的Java实现
一.线性表的抽象数据类型表述 线性表的结构简单,长度允许动态增长或搜索:可以对线性表中的任何数据元素进行访问和查找:允许进行数据的插入和删除操作:求线性表中的指定数据的前驱和后继:合并线性表以及拆分线 ...
随机推荐
- P3366 模板最小生成树
题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz. 输入格式 第一行包含两个整数N,M,表示该图共有N个结点和M条无向边. 接下来M行每行包含三个整数 Xi,Yi,Zi,表 ...
- python——tips
一:python分号使用 每一条语句最后个加个分号:这是c,oc,java,php等语言中不可缺少的部分,但是对于python,分号是可加,可不加的 如:不加分号代码 class Person: na ...
- 基于百度智能云api下的车牌识别系统
车牌识别在高速公路中有着广泛的应用,比如我们常见的电子收费(ETC)系统和交通违章车辆的检测,除此之外像小区或地下车库门禁也会用到,基本上凡是需要对车辆进行身份检测的地方都会用到. 简介 车牌识别系统 ...
- Bad Request - Invalid Hostname HTTP Error 400. The request hostname is invalid.
VS 调试 显示 如下错误 解决办法: 1 打开调试运行中的 IIS Express 2 点击其中一条记录 3 点击配置 4 找到对应项目站点 .添加 <binding protocol=&q ...
- NodeJS - XSS-Attribute
参考:https://owasp-skf.gitbook.io/asvs-write-ups/cross-site-scripting-attribute-xss-attribute/kbid-3-x ...
- RabbitMQ问题汇总
内网通过代理服务器访问MQ服务器,无法连接 使用的是socket连接,要设置socket代理,而不是http代理 Properties prop = System.getProperties(); / ...
- linux关于文件的创建方式
1:文件的创建方式: mkdir 用于创建目录: 语法: mkdir -p 目录名 举例:创建一个在run目录下的一个demo目录: 可以写成: mkdir /run/demo 亦可以写成 mk ...
- 几个Python线程坑,和连接池的坑
urlretrieve 没有超时,需要通过socket来设置 socket.setdefaulttimeout(10) 而且还需要为他设置连接池,所以直接改用requests来下载文件 def dow ...
- 2020.4.28关于pta的总结
0.前言 这次作业针对的是oo程序设计第二单元(5-8周)的作业,在整体当中属于第4到第6次作业. 此三次作业的知识要点为:继承类,多态性,字符串,结构类,接口类. 此三次作业的时间为20.4.12- ...
- CAS无锁机制
1. 背景 传统Synchronized锁:悲观,如果没有获取到锁的情况下,会让当前线程变为阻塞的状态,释放CPU执行权,效率非常低. 乐观锁(自旋):本质上没有锁,没有死锁现象,而且效率比较高,不会 ...