目录

  • 定义
  • 抽象数据类型(ADT)linearList
  • 抽象类 linearList
  • 数组描述的线性表
    • 变长一维数组
    • 类 arrayList
      • 类arrayList的定义
      • 类arrayList的构造函数
      • 类arrayList—checkIndex、get、indexOf函数的实现
      • 删除一个元素
      • 插入一个元素
      • 输出函数output和重载<<

定义

线性表(linear list):零个或多个数据元素的有限序列。

线性表也称有序表(ordered list),它的每一个实例都是元素的一个有序集合。每一个实例的形式为(e0e_0e0​, e1e_1e1​, …, en−1e_n-_1en​−1​),其中n是有穷自然数,是线性表的长度或大小,eie_iei​是线性表的元素,i是元素eie_iei​的索引。

元素本身的结构与线性表的结构无关,在较复杂的线性表中,一个数据元素可以由若干个数据项组成。

n = 0时,线性表称为空表;当n > 0时,e0e_0e0​是线性表的第0个元素或首元素,en−1e_n-_1en​−1​是线性表的最后一个元素。可以认为ei−1e_i-_1ei​−1​先于eie_iei​,eie_iei​先于ei+1e_i+_1ei​+1​,称ei−1e_i-_1ei​−1​是eie_iei​的直接前驱元素,称ei+1e_i+_1ei​+1​是eie_iei​的直接后继元素。除了这种先后关系之外,线性表不再有其他关系。

抽象数据类型(ADT)linearList

ADT linearList
{Data有限个元素的有序集合Operationempty(): 若表空,则返回true,否则返回falsesize(): 返回线性表的大小(即元素个数)get(index): 返回线性表中索引为index的元素indexOf(x): 返回线性表中第一次出现的x的索引。若x不存在,则返回-1erase(index): 删除索引为index的元素,索引大于index的元素其索引减1insert(index, x): 把x插入线性表中索引为index的位置上,索引大于等于index的元素其索引加1output(): 从左到右输出表元素
}

抽象类 linearList

对上面的抽象数据类型ADT linearList,除了用上面的非形式语言方法来描述,我们还可以用抽象类来描述。

template<class T>
class linearList
{public:virtual ~linearList() {};virtual bool empty() const = 0;  // 当且仅当线性表为空时返回truevirtual int size() const = 0; // 返回线性表的元素个数virtual T& get(int theIndex) const = 0; // 返回索引为theElement的元素virtual int indexOf(const T& theElement) const = 0; // 返回元素theElement第一次出现时的索引virtual void erase(int theIndex) = 0; // 删除索引为theIndex的元素virtual void insert(int theIndex, const T& theElement) = 0; // 把theElement插入线性表中索引为theIndex的位置上virtual void output(ostream& out) const = 0; // 把线性表插入输出流out
};

数组描述的线性表

在数组描述中,用数组来存储线性表的元素。假定使用一个一维数组element来存储线性表的元素,arrayLength表示数组长度或容量。数组的每一个位置都可以存储线性表的一个元素,我们需要一个映射,使线性表的一个元素对应数组的一个位置。

要创建一个数组类,以实现抽象数据类型linearList,必须首先选择数组element的类型和数组长度。使用模板类可以很好地解决第一个问题,使用动态数组可以很好地解决第二个问题,首先按照用户估计的长度创建数组,然后在数组空间不足的情况下,动态地增加数组长度。

变长一维数组

一维数组a,线性表元存储在a[0:n-1]中。要增加或减少这个数组的长度,首先要建立一个具有新长度的数组,然后把数组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;
}

创建一个长度为m的数组所需的时间为O(1)

当数组满而需要加大数组长度时,数组长度常常是要加倍的,这个过程称为数组倍增(array doubling)。数组倍增的时间,从渐进意义上考量,不会大于元素插入的总时间。

类 arrayList

我们定义一个C++抽象类linearList的派生类arrayList,它利用映射公式:location(i) = i实现ADT linearListarrayList是一个具体类,所以它必须实现抽象类linearList的所有方法。不仅如此,它还包含基类linearList没有声明的方法,例如,capacitycheckIndex

类arrayList的定义

template<class T>
class arrayList : public linearList<T>
{public:// 构造函数、复制构造函数和析构函数arrayList(int initialCapacity = 10);arrayList(const arrayList<T>&);~arrayList() { delete[] element; }// ADT 方法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);void output(ostream& out) const;// 其他方法int capacity() const { return arraylength; }        // 返回数组element当前的长度
protected:void checkIndex(int theIndex) const;  // 若索引theIndex无效,则抛出异常T* element;            // 存储线性表元素的一维数组int arraylength; // 一维数组的容量int listSize;     // 线性表的元素个数
};

类arrayList的构造函数

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);
}

类arrayList—checkIndex、get、indexOf函数的实现

template<class T>
void arrayList<T>::checkIndex(int theIndex) const
{// 确定索引theIndex在0和listSize - 1之间if (theIndex < 0 || theIndex >= listSize){ostringstream s;s << "index = " << theIndex << " size = " << listSize;throw illegalParameterValue(s.str());}
}template<class T>
T& arrayList<T>::get(int theIndex) const
{// 返回索引为theIndex的元素// 若此元素不存在,则抛出异常checkIndex(theIndex);return element[theIndex];
}template<class T>
int arrayList<T>::indexOf(const T& theElement) const
{// 返回元素theElement第一次出现时的索引// 若该元素不存在,则返回-1// 查找元素 theElementint theIndex = (int)(find(element, element + listSize, theElement) - element);// 确定元素theElement是否找到return (theIndex == listSize) ? -1 : theIndex;
}

删除一个元素

为了从线性表中删除索引为theIndex的元素,首先要确定线性表包含这个元素,然后删除这个元素。若没有这个元素,则抛出类型为illegalIndex的异常。

当要删除索引为theIndex的元素时,利用copy算法把索引从theIndex + 1listSize - 1的元素向左移动一个位置,然后把变量listSize的值减1。

template<class T>
void arrayList<T>::erase(int theIndex)
{//删除索引为theIndex的元素,若该元素不存在,则抛出异常checkIndex(theIndex);// 有效索引,移动其索引大于theIndex的元素copy(element + theIndex + 1, element + listSize, element + theIndex);element[--listSize].~T(); // 调用析构函数(显示调用析构)
}

插入一个元素

要在表中索引为theIndex的位置上插入一个新元素,首先把索引从theIndexlistSize-1的元素向右移动一个位置,然后将新元素插入索引为theIndex的位置,最后将变量listSize的值加1,copy_backward函数是从最右端开始移动元素的。如果在插入前,数组空间已满,那么将数组长度倍增。

template<class T>
void arrayList<T>::insert(int theIndex, const T& theElement)
{// 在索引theIndex处插入元素theElementcheckIndex(theIndex);if (listSize == arrayLength){// 若数组空间已满,数组长度倍增changeLength1D(element, arrayLength, 2 * arrayLength);arrayLength *= 2;}// 把元素向右移动一个位置copy_backward(element + theIndex, element + listSize, element + listSize + 1);element[theIndex] = theElement;listSize++;
}
  • 如果我们总是按一个乘法因子来增加数组长度,那么实施一系列线性表的操作所需要的时间与不用改变数组长度时相比,至多增加一个常数因子。

输出函数output和重载<<

template<class T>
void arrayList<T>::output(ostream& out)const
{//把线性表插入输出流copy(element, element + listSize, ostream_iterator<T>(out, " ");
}
//重载流插入符(insertion operator)<<
template<class T>
ostream& operator<< (ostream& out, const arrayList<T>& x)
{x.output(out);return out;
}

数据结构之线性表—数组描述相关推荐

  1. 数据结构与算法笔记(二) 线性表(数组描述)

    c++常用的数据描述方法是数组描述和链式描述,线性表可以用来说明这两方法,先介绍数组描述的线性表.后面再介绍链式描述的线性表. C++ STL容器vector和list相当于线性表的数组描述和链式描述 ...

  2. 用Java描述数据结构之线性表的链式存储(链表),模拟LinkedList实现

    上一篇介绍了顺序表:用Java描述数据结构之线性表的顺序存储(顺序表),ArrayList及其方法的介绍 上一篇博客中说明了什么是线性表--线性表就是一个个数据元素逻辑上以一对一的相邻关系(但是在物理 ...

  3. 用Java描述数据结构之线性表的顺序存储(顺序表),ArrayList及其方法的介绍

    我们先来想一想什么是线性表? 线性表是最基本.最简单.也是最常用的一种数据结构.线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列. 线性表中数据元素之 ...

  4. c语言如何删除数组中的某一个元素_数据结构之线性表高效删除重复元素

    刚刚学完数据结构之线性表中关于顺序表和单链表的知识,我们知道顺序表中存储数据的结构是一个数组,对于数组来说,在尾部插入.删除元素是比较高效的,但是如果在中间或者开头插入.删除元素,就会涉及数据的搬移, ...

  5. 数据结构之线性表----一文看懂顺序表、单链表、双链表、循环链表

    ​ 线性表是数据结构中比较基础的内容,不过也是入门的所需要客服的第一个难关.因为从这里开始,就需要我们动手编程,这就对很多同学的动手能力提出了挑战.不过这些都是我们需要克服的阵痛,学习新的知识总是痛苦 ...

  6. Java数据结构(1.1):数据结构入门+线性表、算法时间复杂度与空间复杂度、线性表、顺序表、单双链表实现、Java线性表、栈、队列、Java栈与队列。

    数据结构与算法入门 问题1:为什么要学习数据结构          如果说学习语文的最终目的是写小说的话,那么能不能在识字.组词.造句后就直接写小说了,肯定是不行的, 中间还有一个必经的阶段:就是写作 ...

  7. 数据结构 基于线性表的图书信息管理

    数据结构 基于线性表的图书信息管理 实验前的准备 IDE的选择 C语言中指针与结构体 实验目的 实验内容 1.基于顺序存储结构的图书信息表的创建和输出 代码 实验中遇到的问题 ① 实验中遇到的问题 ② ...

  8. 数据结构:线性表顺序存储

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.线性表(List):0个或多个数据结构的有限序列 二.线性表的顺序存储结构 1.顺序存储定义 2.顺序存储方式 3.顺序 ...

  9. 数据结构之线性表(附代码)

    数据结构 之 线性表(附代码) 线性表思维导图: 线性表定义(逻辑结构): 一.顺序表 1.顺序表思维导图: 2.顺序表的逻辑结构: 3.顺序表基本操作的功能实现: 1.线性表的静态定义: 2.线性表 ...

最新文章

  1. Confluence 6 启用远程 API
  2. 家庭记账软件 —— Java
  3. windows下flv视频网站进度条随意拖放[转]
  4. 【python】python redis的安装与使用
  5. 利用for循环调用插入方法批量插入 一条失败_算法与数据结构(1):基础部分——以插入排序为例...
  6. 如何让大数据从发现价值到创造价值
  7. Android Studio(9)--添加应用资源
  8. FlashDevelop 遇到的Process not responding 问题
  9. 正则表达式最好的书籍_正则表达式的最佳做法
  10. python如何计算等额本息还款_等额本息还款方式计算
  11. input 时分秒输入_JavaScript实现input框获取系统默认年月日时分秒
  12. 【百度网盘】二维码不显示,账号密码无法登录,显示百度认证无法访问此页
  13. JavaScript的前生今世
  14. 【Python毕业设计源码】python主机硬件配置推荐系统
  15. 【ESP32Arduino+MPU6050 dmp姿态解算】学习笔记 PlatformIO 复制即可使用
  16. 软件过程管理第一章(绪论)
  17. 7-33 地下迷宫探索 (30 分)-简单dfs
  18. opencv 双目摄像头标定
  19. rdkit 读写分子操作
  20. 第六届“智慧杯“大赛编程思维(C++普及组)赛后解析(详细)

热门文章

  1. EAR 文件格式 简介
  2. 大航海时代:葡萄牙、西班牙率先出发,英国为何成为最大赢家?
  3. 内核架构师必备技能:编写自己的kconfig框架plus
  4. LeetCode-1049. 最后一块石头的重量 II
  5. zcmu-1668: 高桥和低桥
  6. 为什么PSP、PS3再便宜我都不会去买
  7. 制作静态页面的悬浮框
  8. 产品读书《高效能阅读》《深阅读》《如何有效阅读一本书》
  9. 《网页设计与欣赏》大学选修课论文
  10. iOS 网络编程 (四)JSON解析