线性表顺序存储结构

线性表的顺序存储是用一组地址连续的存储单元依次存储线性表的数据元素。假设线性表的每个数据元素需占用K个存储单元,并以元素所占的第一个存储单元的地址作为数据元素的存储地址。则线性表中序号为i的数据元素的存储地址LOC(a i )与序号为i+1 的数据元素的存储地址LOC(a i+1 )之间的关系为LOC(a i+1 ) = LOC(a i ) + K通常来说,线性表的i号元素a i 的存储地址为LOC(a i ) = LOC(a 0 ) + i×K 其中LOC(a 0 )为 0 号元素a 0 的存储地址,通常称为线性表的起始地址。

线性表的这种机内表示称作线性表的顺序存储。它的特点是,以数据元素在机内存储地址相邻来表示线性表中数据元素之间的逻辑关系。每一个数据元素的存储地址都和线性表的起始地址相差一个与数据元素在线性表中的序号成正比的常数。由此,只要确定了线性表的起始地址,线性表中的任何一个数据元素都可以随机存取,因此线性表的顺序存储结构是一种随机的存储结构。

  由于高级语言中的数组具也有随机存储的特性,因此在抽象数据类型的实现中都是使用数组来描述数据结构的顺序存储结构。我们看到线性表中的数据元素在依次存放到数组中的时候,线性表中序号为 i 的数据元素对应的数组下标也为 i,即数据元素在线性表中的序号与数据元素在数组中的下标相同。 在这里需要注意的是,如果线性表中的数据元素是对象时,数组存放的是对象的引用,即线性表中所有数据元素的对象引用是存放在一组连续的地址空间中。如图 3-2 所示

  在数组中添加数据元素,通常是在数组中下标为 i (0 ≤ i ≤ n)的位置添加数据元素,而将原来下标从 i 开始的数组中所有后续元素依次后移。整个操作过程可以通过图 3-3 说明。

使用 Java 语言实现整个操作过程的关键语句是for (int j=n; j>i; j--)a[j] = a[j-1];a[i] = e;

  与在数组中添加数据元素相对的是在数组中删除数据元素,与添加类似,删除操作也通常是删除数组中下标为 i (0 ≤ i < n)的元素,然后将数组中下标从 i+1 开始的所有后续元素依次前移。删除操作过程也可以通过图 3-4 说明

使用 Java 语言实现整个操作过程的关键语句是for (int j=i; j

List接口:*** 线性表*/public interface List {/***线性表的长度*/public int size();/*** 判断线性表是否为空*/public boolean isEmpty();/*** 判断线性表中是否包含某个元素*/public boolean contains(Object element);/*** 判断线性表中是否包含某个元素*/public int indexOf(Object element);/***在表中插入元素*/public void add(Object element);/***在索引处插入元素*/public void insert(int index,Object element) throws IndexOutOfBoundsException;/***删除线性表中第一个与 e 相同的元素*/public boolean remove(Object element);/***在表中移除序号为i的某个元素*/public Object remove(int i)throws IndexOutOfBoundsException;/***返回线性表中序号为i的元素*/public Object get(int i)throws IndexOutOfBoundsException;}   顺序存储结构实现线性表public class ListArray implements List {private final int LEN = 8; //数组的默认大小private int size; //线性表中数据元素的个数private Object[] elements; //数据元素数组public ListArray() {size = 0;elements = new Object[LEN];}@Overridepublic int size() {return size;}@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic boolean contains(Object element) {for (int i = 0; i < size; i++) {if (elements[i].equals(element))return true;}return false;}@Overridepublic int indexOf(Object element) {for (int i = 0; i < size; i++) {if (elements[i].equals(element))return i;}return -1;}@Overridepublic void add(Object element) {if (size >= elements.length)expandSpace();elements[++size]=element;}@Overridepublic void insert(int index, Object element) throws IndexOutOfBoundsException {if (index < 0 || index > size)throw new IndexOutOfBoundsException();if (size >= elements.length)expandSpace();for (int j = size; j > index; j--)elements[j] = elements[j - 1];elements[index] = element;size++;return;}private void expandSpace() {Object[] a = new Object[elements.length * 2];for (int i = 0; i < elements.length; i++) {a[i] = elements[i];elements = a;}}@Overridepublic boolean remove(Object element) {int i = indexOf(element);if (i<0)return false;remove(i);return true;}@Overridepublic Object remove(int index) throws IndexOutOfBoundsException {if (index < 0 || index > size)throw new IndexOutOfBoundsException();Object obj=elements[index];for (int j =index; j size)throw new IndexOutOfBoundsException();return elements[index];}}

线性表链式存储结构

链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为 结点(node)。

  在 Java 中没有显式的指针类型,然而实际上对象的访问就是使用指针来实现的,即在Java 中是使用对象的引用来替代指针的。因此在使用 Java 实现该结点结构时,一个结点本身就是一个对象。结点的数据域 data 可以使用一个 Object 类型的对象来实现,用于存储任何类型的数据元素,并通过对象的引用指向该元素;而指针域 next 可以通过节点对象的引用来实现。  由于数据域存储的也是对象引用,因此数据实际上和图 3-2 中一样,是通过指向数据的物理存储地址来完成存储的,但是在后面叙述的方便,我们在图示中都将数据元素直接画到了数据域中,请读者注意实际的状态与之是有区别的。

上面的单链表结点结构是结点的一种最简单的形式,除此之外还有其他不同的结点结构,但是这些结点结构都有一个数据域,并均能完成数据元素的存取。为此在使用 Java 定义单链表结点结构之前先给出一个结点接口,在接口中定义了所有结点均支持的操作,即对结点中存储数据的存取。

节点接口public interface Node {//获取结点数据域public Object getData();//设置结点数据域public void setData(Object obj);}单链表节点public class SLNode implements Node {private Object element;private SLNode next;public SLNode() {this(null,null);}public SLNode(Object ele, SLNode next){this.element = ele;this.next = next;}public SLNode getNext(){return next;}public void setNext(SLNode next){this.next = next;}/**************** Methods of Node Interface **************/public Object getData() {return element;}public void setData(Object obj) {element = obj;}}

单链表实现

public class ListSLinked implements List{private SLNode head; //单链表首结点引用private int size; //线性表中数据元素的个数public ListSLinked () {head = new SLNode();size = 0;}//辅助方法:获取数据元素 e 所在结点的前驱结点private SLNode getPreNode(Object e){SLNode p = head;while (p.getNext()!=null)if (p.getNext().getData().equals(e)) return p;else p = p.getNext();return null;}//辅助方法:获取序号为 0<=i0; i--) p = p.getNext();return p;}//获取序号为 0<=i0; i--) p = p.getNext();return p;}//返回线性表的大小,即数据元素的个数。public int getSize() {return size;}//如果线性表为空返回 true,否则返回 false。public boolean isEmpty() {return size==0;}//判断线性表是否包含数据元素 epublic boolean contains(Object e) {SLNode p = head.getNext();while (p!=null)if (p.getData().equals(e)) return true;else p = p.getNext();return false;}//返回数据元素 e 在线性表中的序号public int indexOf(Object e) {SLNode p = head.getNext();int index = 0;while (p!=null)if (p.getData().equals(e)) return index;else {index++; p = p.getNext();}return -1;}//将数据元素 e 插入到线性表中 i 号位置public void insert(int i, Object e) throws IndexOutOfBoundsException {if (i<0||i>size)throw new IndexOutOfBoundsException("错误,指定的插入序号越界。");SLNode p = getPreNode(i);SLNode q = new SLNode(e,p.getNext());p.setNext(q);size++;return;}//删除线性表中序号为 i 的元素,并返回之public Object remove(int i) throws IndexOutOfBoundsException {if (i<0||i>=size)throw new IndexOutOfBoundsException("错误,指定的删除序号越界。");SLNode p = getPreNode(i);Object obj = p.getNext().getData();p.setNext(p.getNext().getNext());size--;return obj;}//删除线性表中第一个与 e 相同的元素public boolean remove(Object e) {SLNode p = getPreNode(e);if (p!=null){p.setNext(p.getNext().getNext());size--;return true;}return false;}//返回线性表中序号为 i 的数据元素public Object get(int i) throws IndexOutOfBoundsException {if (i<0||i>=size)throw new IndexOutOfBoundsException("错误,指定的序号越界。");SLNode p = getNode(i);return p.getData();}}

基于时间的比较  线性表的操作主要有查找、插入、删除三类操作。对于查找操作有基于序号的查找,即存取线性表中 i 号数据元素。由于数组有随机存取的特性,在线性表的顺序存储实现中可以在Θ(1)的时间内完成;而在链式存储中由于需要从头结点开始顺着链表才能取得,无法在常数时间内完成,因此顺序存储优于链式存储。查找操作还有基于元素的查找,即线性表是否包含某个元素、元素的序号是多少,这类操作线性表的顺序存储与链式存储都需要从线性表中序号为 0 的元素开始依次查找,因此两种实现的性能相同。综上所述,如果在线性表的使用中主要操作是查找,那么应当选用顺序存储实现的线性表。对于基于数据元素的插入、删除操作而言,当使用数组实现相应操作时,首先需要采用顺序查找定位相应数据元素,然后才能插入、删除,并且在插入、删除过程又要移动大量元素;相对而言链表的实现只需要在定位数据元素的基础上,简单的修改几个指针即可完成,因此链式存储优于顺序存储。对于基于序号的插入、删除操作,因为在顺序存储中平均需要移动一半元素;而在链式存储中不能直接定位,平均需要比较一半元素才能定位。因此顺序存储与链式存储性能相当。综上所述,如果在线性表的使用中主要操作是插入、删除操作,那么选用链式存储的线性表为佳。

实验一 线性表的顺序存储与实现_线性表的存储结构(java)相关推荐

  1. 实验一 线性表的顺序存储与实现_【自考】数据结构中的线性表,期末不挂科指南,第2篇

    线性表 这篇博客写的是线性表相关的内容,包括如下部分,先看下有木有期待 啥是线性表 线性表的顺序存储 线性表的基本运算在顺序表上的实现 线性表的链式存储 线性表的基本运算在单链表上的实现 循环链表与双 ...

  2. 实验一 线性表的顺序存储与实现_数据结构篇之单链表的创建以及实现

    上次咱们已经一起分享了线性表的顺序存储的基本创建以及一些运算方法的实现,那么这次咱们主要来研究线性表的链式存储,俗称单链表,咱们知道顺序表在建立的时候要注意需要建立一块连续的空间,所以需要使用数组在内 ...

  3. 实验一 线性表的顺序存储与实现_程序员:数据结构与算法,线性表介绍

    线性表 线性表(list):零个或多个数据元素的有限序列. 举个例子:一个班的小朋友,一个跟着一个排队,当中的每个小朋友都知道他前面的是谁,后面的是谁,如同一根线把他们串联起来.就可以称之为线性表. ...

  4. 线性表的顺序存储 c语言表达,线性表的基本操作顺序存储(C语言).doc

    线性表的基本操作顺序存储(C语言) #include#include#include#define LIST_INIT_SIZE/*线性表存储空间初始分配量*/#define LISTINCREMEN ...

  5. java 线性表的表示和实现_线性表中顺序表的的理解和实现(java)

    线性表的顺序表示指的是用一组地址连续的存储单元以此存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像.通常,称这种存储结构的线性表为顺序表.特点是:逻辑上相邻的数据元素,其物理次序上也 ...

  6. java设计一个顺序表类的成员函数_顺序表代码讲解以及实现

    用C语言编写一个有关顺序表的程序代码 创建一个顺序表,其数据元素类型为整型: 在该顺序表中插入数据(#include #include #define MaxSize 50 typedef char ...

  7. 提交表单数据到数据库_普通表单不仅适用于数据库

    提交表单数据到数据库 您也可以将类似的规则应用于数据对象类型. (You can apply similar rules to data object types, too.) You probabl ...

  8. 广义表头尾链表存储结构_单向循环链表的存储结构和操作

    单向循环链表的存储结构 单向循环链表(Circular Linked List)是单向链表的一种扩充,当单向链表带有头结点时,把单向链表中尾结点的指针域由空指针改为头结点的指针(当单向链表不带头结点时 ...

  9. mysql动态表单设计与实现_动态表单的数据库结构设计

    利用在线编辑器设计的表单,包含输入框,明细表(动态添加行)等需要存储到数据库的信息,现在有三种思路: 1.一个表单对应数据库的一张或多张物理表(主从表),这种设计在很多业务的情况下,其数据库的物理表会 ...

  10. mysql一张表100亿条数据_一个表有100亿条记录,如何优化

    我们的数据库还在设计阶段.我们预计数据量将会很大,一年的时间里,一张表,就会产生100亿条数据,表结构,如下id,userid,createddate,等等正常情况下,100亿条记录如果都存在一个表里 ...

最新文章

  1. flex4实现图片的动态切换
  2. 对现有代码的分析方法随想
  3. gradle build running很慢
  4. LaTeX技巧如何拆分源文件并且分别编译
  5. 7-19 求链式线性表的倒数第K项 (20 分)(思路分析+极简代码+超容易理解)
  6. Teradata天睿公司任命Steve McMillan为总裁兼首席执行官
  7. php mysql 操作函数_PHP操作mysql函数详解,mysql和php交互函数
  8. 【Python笔记】集合
  9. 常见linux服务器系统异常问题
  10. 阿里maven仓库地址
  11. ICEM: 合并混合网格
  12. 精 挑 细 选 http://acm.nyist.net/JudgeOnline/problem.php?pid=263
  13. GAMMA初学笔记一
  14. Vokenization:一种比GPT-3更有常识的视觉语言模型
  15. SimpleDateFormat大写Y和小写y的区别
  16. 微信文件传输助手网页版
  17. TypeScript基础+进阶
  18. Greenplum——基于Greenplum-Spark Connector的Spark脚本开发及遇到的坑
  19. java 制表符 宽度不够_有没有办法强制使用制表符而不是Java中的空格?
  20. Eclipse中导入外部jar包——添加lib

热门文章

  1. 一个简单的Matlab面向对象编程实例
  2. Atitit 常见编程语言读写数据库的api目录1.1. Php pdo 11.2. Java jdbctmpltr 11.3. Nodejs mysql模块 11.4. Pytho
  3. Atitit 数据校验法 目录 1. 用内置表单数据校验 简单快捷 1 1.1. input 元素的校验约束 — starting simple 1 1.1.1. required 属性 1 1.1
  4. Atitit 常见聚合运算与算法 目录 1.1. 单行函数,vs 那就是聚合函数 1 1.2. 聚合分类 哈希聚合 标量聚合 流聚合 1 1.3. 常见聚合函数 mysql oracle等 1 r
  5. Atitit 编程 序列化技术点 概念原理v2 1. 序列化: 1 2. 序列化的目的 1 2.1. 为了传输 或者存储 1 3. 应用场合 1 3.1. Form提交url 1 3.2. For
  6. atitit uke产品线 attilax总结.docx 1. 知识聚合 知识检索 产品线 1 2. 爬虫产品线 1 3. 发帖机产品线 1 4. 发动机产品线 1 5. O2o产品线(旅游
  7. Atitit. 提升存储过程与编程语言的可读性解决方案v3 qc25.docx
  8. Atitit.分布式远程调用  rpc  rmi  CORBA的关系
  9. Atitit.异常的设计原理与 策略处理 java 最佳实践 p93
  10. PHOTOSHOP使用总结