数组描述线性表(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实现
一.线性表的抽象数据类型表述 线性表的结构简单,长度允许动态增长或搜索:可以对线性表中的任何数据元素进行访问和查找:允许进行数据的插入和删除操作:求线性表中的指定数据的前驱和后继:合并线性表以及拆分线 ...
随机推荐
- apt-get install 出现could not open lock file /var/lib/dpkg/lock错误问题
apt-get install 经常出现 could not open lock file /var/lib/dpkg/lock -open 错误问题 一种解决办法 1.切换到root用户 su ~ ...
- maven插件实现项目一键“run maven、debug maven”等命令 => 插件名:“maven helper”
1.在IDEA中下载插件 2.使用 总结:通过 "maven helper" 插件即可通过命令实现对项目的一键管理
- C#学习之详解C#Break ,Continue, Return
C#编程语法中break ,continue, return这三个常用的关键字的学习对于我们编程开发是十分有用的,那么本文就向你介绍break ,continue, return具体的语法规范. C# ...
- 第一天1h
//摄氏度和华氏度之间的换算//20211120//ZhangWenjing#include<stdio.h>int main(void){ int f = 0; int c = 0; s ...
- python pip安装三方库失败
Collecting pip WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None ...
- git的回退以及合并,删除什么的
有时候不小心合并了别的分支中的commit.我们需要回退某些提交记录.可以通过reset来操作,reset 会回退到指定commit.这种方式会删除记录,我们最好使用revert命令来操作 git r ...
- BlenderGIS记录
blender GIS 的插件名:"3Dview:blenderGIS" 具体使用方法看文档. 选择地图时选择bing地图会快一点.如果能挂梯子可以选择google地图 shift ...
- java8 stream按某个字段分组,允许分组字段是null
Map<String, List<Dto>> deviceMap = deviceList.stream().collect(Collectors.groupingBy(Dto ...
- Axure RP Extension for Chrome 0.6.2安装和详解
1.当我们用网页访问一个本地页面时就会出现这种问题,提示你要安装浏览器的扩展程序包,以下有搜狗浏览器如何安装,qq浏览器
- What Are You Weighting For?
A basic strength routine can change your life Strength training isn't just about getting six-pack ab ...