顺序表

线性表的顺序存储结构

1、数组是实现顺序存储结构的基础。

特点:地址连续确定,容量固定,随机存取T(n) = O(1)

一维数组占用一块内存空间,数组的存储单元个数成为数组容量,也成为数字长度。每个存储单元的地址是连续的,即每个元素连续存储。(反映了顺序表的逻辑结构)。

存取任何一个元素的时间复杂度是O(1)的数据结构成为随机存储结构,数组也是随机存储结构。

2、顺序表

线性表的顺序存储结构成为顺序表。数据元素在内存的物理存储次序反映了线性表数据元素之间的逻辑次序。

当顺序表使用的数组容量不够时,解决数据溢出的办法是,申请另一个更大容量的数组并进行数组元素赋值。(延伸:浅拷贝和深拷贝)

顺序表类声明

package SeqList;public class SeqList extends Object
{protected Object[] element;                            //对象数组,保护成员protected int n;                                       //顺序表元素个数(长度)//1. 构造、存取public SeqList(int length)                             //构造容量为length的空表{this.element = new Object[length];                 //申请数组的存储空间,元素为null。//若length<0,Java抛出负数组长度异常 java.lang.NegativeArraySizeExceptionthis.n = 0;}public SeqList()                                       //创建默认容量的空表,构造方法重载{this(64);                                          //调用本类已声明的指定参数列表的构造方法}public SeqList(T[] values)                             //构造顺序表,由values数组提供元素,忽略其中空对象{this(values.length);                               //创建容量为values.length的空表//若values==null,用空对象调用方法,Java抛出空对象异常NullPointerExceptionfor (int i=0; i<values.length; i++)                //复制数组元素,O(n)this.element[i] = values[i];                   //对象引用赋值this.n = element.length;}public boolean isEmpty()                               //判断顺序表是否空,若空返回true,O(1){return this.n==0;}public int size()                                      //返回顺序表元素个数,O(1){return this.n;}//存取操作public T get(int i)                                    //返回第i个元素,0≤i<n。若i越界,返回null。O(1){if (i>=0 && i<this.n)return (T)this.element[i];                     //返回数组元素引用的对象,传递对象引用
//      return this.element[i];                            //编译错,Object对象不能返回T对象return null;}    //设置第i个元素为x,0≤i<n。若i越界,抛出序号越界异常;若x==null,抛出空对象异常。O(1)public void set(int i, T x){if (x==null)throw new NullPointerException("x==null");     //抛出空对象异常if (i>=0 && i<this.n)this.element[i] = x;else throw new java.lang.IndexOutOfBoundsException(i+"");//抛出序号越界异常}//返回顺序表所有元素的描述字符串,形式为“(,)”。覆盖Object类的toString()方法public String toString(){String str=this.getClass().getName()+"(";          //返回类名if (this.n>0)str += this.element[0].toString();             //执行T类的toString()方法,运行时多态for (int i=1; i<this.n; i++)str += ", "+this.element[i].toString();        //执行T类的toString()方法,运行时多态return str+") ";                                   //空表返回()}
}

操作的效率分析

O(1):isEmpty(), size(), get(), set()
O(n):toString()需要遍历顺序表

顺序表插入操作

1、对要插入的数据元素进行判断,是否为空
2、插入的数据元素的位置,是否越界
这里有两种处理:①采取容错措施,若 i<0,则插入x在最前面;若 i>n,则插入x在最后面    ②不处理,返回错误信息
3、是否溢出,若溢出,申请更大容量的数组并复制全部数组元素
4、移动数据,空出位置(主要的时间花费)
5、插入数据元素
插入过程图解:
//2. 顺序表的插入操作//插入x作为第i个元素,x!=null,返回x序号。若x==null,抛出空对象异常。O(n)//对序号i采取容错措施,若i<0,插入x在最前;若i>n,插入x在最后public int insert(int i, T x){if (x==null)                                       //判断插入的元素是否为空throw new NullPointerException("x==null");     //抛出空对象异常if (i<0)       i=0;                                //插入位置i容错,插入在最前if (i>this.n)  i=this.n;                           //插入在最后Object[] source = this.element;                    //数组变量引用赋值,source也引用element数组if (this.n==element.length)                        //若数组满,则扩充顺序表的数组容量{this.element = new Object[source.length*2];    //重新申请一个容量更大的数组for (int j=0; j<i; j++)                        //复制当前数组前i-1个元素this.element[j] = source[j];}for (int j=this.n-1; j>=i; j--)                    //从i开始至表尾的元素向后移动,次序从后向前this.element[j+1] = source[j];this.element[i] = x;this.n++;return i;                                          //返回x序号}public int insert(T x)                                 //顺序表尾插入x元素,返回x序号。成员方法重载{return this.insert(this.n, x);                     //插入操作中,this.n加1}
对顺序表进行插入操作时,算法所花费的时间主要用于移动元素,插入一个元素平均需要移动顺序表元素总量的一半,时间复杂度是O(n)。

顺序表删除操作

顺序表删除元素ai,必须将ai之后的ai+1、ai+2、...、an-1元素依次向前移动

1、先将ai后的数据依次向前移动

2、将最后一个数据元素释放空间

//3. 顺序表的删除操作public T remove(int i)          //删除第i个元素,0≤i<n,返回被删除元素。若i越界,返回null。//??若i越界,抛出序号越界异常{if (this.n>0 && i>=0 && i<this.n) {T old = (T)this.element[i];                    //old中存储被删除元素for (int j=i; j<this.n-1; j++)this.element[j] = this.element[j+1];       //元素前移一个位置this.element[this.n-1]=null;                   //设置数组元素对象为空,释放原引用实例this.n--;return old;                                    //返回old局部变量引用的对象,传递对象引用}return null;//throw new IndexOutOfBoundsException(i+"");         //抛出序号越界异常}

删除元素操作所花费的 时间主要用于移动元素。删除一个元素平均移动n/2个元素,时间复杂度为O(n)。

顺序表查找操作

顺序查找,在查找过程中,需要将key与顺序表元素逐个比较是否相等。
//4. 顺序查找
//顺序查找首次出现的与key相等元素,返回元素序号i,0≤i<n;查找不成功返回-1。
//若key==null,Java抛出空对象异常NullPointerException
public int search(T key)
{for (int i=0; i<this.n; i++){if (key.equals(this.element[i]))               //执行T类的equals(Object)方法,运行时多态return i;}return -1;                                         //空表或未找到时
}
 public boolean contains(T key)                         //判断是否包含关键字为key元素{return this.search(key)!=-1;}

顺序查找的次数取决于元素位置,T(n)=O(n)

顺序表的浅拷贝与深拷贝

浅拷贝:一个类的拷贝构造方法通常实现为成员变量逐域赋值,即将当前对象的各成员变量赋值为实际参数对应的各成员变量值,称为浅拷贝。
public SeqList(SeqList<T> list)                      //浅拷贝构造方法,复制对象{this.n = list.n;                                   //int整数赋值,复制了整数值this.element = list.element;                       //数组引用赋值,两个变量共用一个数组,错误}

数组是引用数据类型,数组引用赋值传递了数组的引用信息,没有申请新的存储空间,this和list引用同一个数组,修改、插入、删除等操作时会同时结果相互影响

e.g:  
 SeqList<String> lista = new SeqList<String>({"A","B","C","D","E"});
SeqList<String> listb = new SeqList<String>(lista);       
        lista.remove(0);
lista = SeqList(B,C,D,E),  listb =
Exception in thread "main" java.lang.NullPointerException
在lista中进行remove(0)操作是对数组进行删除,实际上也删除了listb的元素,但是listb的结构没有改变。
深拷贝:不仅要复制对象的所有基本类型成员变量值,还要为引用类型变量申请存储空间,并复制其中所有元素。
public SeqList(SeqList<? extends T> list)              //拷贝构造方法,深拷贝,复制list
{                                      this.n = list.n; this.element = new Object[list.element.length];    //申请一个数组for (int i=0; i<list.n; i++)                       //复制list所有元素,O(n)this.element[i] = list.element[i];             //对象引用赋值,没有创建新对象}
}

这里的深拷贝申请了新的数组空间,进行插入和删除操作不会影响对方对象。

但是由于对象赋值是引用赋值,深拷贝没有复制元素对象,修改其中的实例,仍会影响对方。如下图
∴深拷贝应该复制每个引用类型成员变量所引用的数组或对象,直至该对象可达的所有对象。如下图所示。

顺序表比较相等

两个线性表相等是指,它们各对应元素相等并且长度相等。
SeqList<T>类声明覆盖equals(Object)方法
//6. 顺序表比较相等public boolean equals(Object obj)                      //比较两个顺序表是否相等。覆盖。O(n){if (this==obj)                                     //若this和obj引用同一个顺序表实例,则相等return true;if (obj instanceof SeqList<?>)                     //若obj引用顺序表实例。SeqList<?>是所有SeqList<T>的父类{SeqList<T> list = (SeqList<T>)obj;             //声明list也引用obj引用的实例if (this.n==list.n)                            //比较两者长度是否相等{for (int i=0; i<this.n; i++)               //比较两个顺序表的所有元素是否相等if (!(this.get(i).equals(list.get(i))))//equals(Object)运行时多态return false; return true;}}return false;}    

时间复杂度是O(n)。

顺序表——基本概念、顺序表类实现、基本操作相关推荐

  1. C和C++线性表基本概念

    C和C++线性表基本概念 线性表基本概念 线性表定义 数学定义 性质 练习 线性表的操作 线性表基本概念 线性表定义 线性表(List)是零个或多个数据元素的集合 线性表中的数据元素之间是有顺序的 线 ...

  2. 顺序查找的概念及实现代码详解

    文章目录 顺序查找的概念 一般线性表的顺序查找(顺序表) 完整代码 平均查找长度 一般线性表的顺序查找(链表) 完整代码 平均查找长度 顺序查找的优缺点 关键字有序的顺序表的顺序查找 平均查找长度 顺 ...

  3. 广义表的概念及存储表示

    文章目录 广义表的概念 广义表的特性 广义表的表头和表尾 广义表的链接存储表示 头尾表示法 扩展线性链表表示法 广义表的概念 广义表的定义:广义表是 n ( n ≥ 0 ) n\ (n≥0) n (n ...

  4. 数据结构 线性表java_java数据结构--线性表

    一.线性表基本概念 线性表是其组成元素间具有线性关系的一种线性结构,是由n个数据类型相同的元素构成的有限序列.其具有"一对一"的逻辑关系,与位置有关,除了头尾元素之外,每一个元素都 ...

  5. php显示html表单内容,HTML表单是什么?HTML表单内容的详细介绍(附代码)

    HTML 表单是用于搜集不同类型的用户输入的,表单是一个包含表单元素的区域:表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息的元素:表单使用表单标签( )定义. 一.介 ...

  6. 数据结构与算法之线性表(超详细顺序表、链表)

    原创公众号:bigsai 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 通过前面数据结构与算法基础知识我么知道了数据结构的一些概念和重要性,那么我们今天总结下线性表相关的内容 ...

  7. 顺序表专题(1)——顺序表

    顺序表 概念 基本形式 顺序表基本布局 元素外置的顺序表基本布局 图解 顺序表的实现 一体式实现 分离式结构 图解 元素存储区操作 元素存储区替换 元素存储区扩充 概念 需求:将一组(通常是同一类型) ...

  8. 数据结构之【线性表】(顺序表、链表的基本操作实现)

    概念 线性表:是N个数据元素的有限序列. 顺序表:用一组地址连续的存储单元依次存储[线性表 ]的数据元素.(区别于有序表:表中的数据元素存在非递增或非递减有序) 链表:用一组任意的存储单元来存储[线性 ...

  9. mysql 线性表_数据结构-线性表之顺序表

    线性表 (1)逻辑结构和物理结构 物理结构:数据元素在内存中真实的存放次序,有可能是连续存放的,也可能是散落于内存里. 逻辑结构:为了便于描述数据元素之间的关系,我们想象出数据之间应该有某种的对应关系 ...

最新文章

  1. linux给普通用户sudo权限
  2. VS修改项目名后出现的提示(warning MSB8028: The intermediate directory (Debug\) contains files shared from anoth)
  3. props写法_好程序员web前端培训React中事件的写法总结
  4. python pipe stdout 实现cat|grep 功能
  5. android 6.0 logcat机制(二)logcat从logd中获取log保存到文件中
  6. c语言形考作业1答案,c语言程序设计形考任务二答案.doc
  7. svn 自动同步到web站点目录post-commit.bat
  8. .NEt中的继承、聚合和组合
  9. 原创--DataGrid自动分页例子,通过存储过程
  10. Centos6.x服务器配置jdk+tomcat+mysql环境
  11. 如何在GO语言中使用Kubernetes API?
  12. 用JavaScript简单编程——基础篇
  13. java sap_SAP系统安装之JAVA
  14. 推荐几个高质量的软件测试实战项目
  15. Android 6.0 AppOps 简介
  16. 400+人支持的技能树又又又更新了,来看看对我们的学习有没有帮助呢?Python技能树评测
  17. python 英语翻译_Python 实现中英文翻译
  18. 重温与解析《最后生还者》的互动叙事精髓(下)
  19. RTE2022即将开幕 声网发布RTE行业首本专业书籍《实时万象》
  20. 《Windows程序设计》读书笔九 子窗口控件

热门文章

  1. cad抠图 lisp_用Autolisp对AutoCAD进行二次改造
  2. 分享在实际项目中积累的硬件调试经验 - 调试方法,以及常见调试案例
  3. java 简单文件加密
  4. 石头剪子布(字符串)c语言,石头、剪刀、布程序,C语言模拟
  5. BeanUtilsVo.copyProperties源码分析
  6. java文件 默认打开方式_修改文件的默认打开方式(亲测有效)
  7. 【青蛙旅行】想给呱儿子买外挂?小心有诈!
  8. ESP32 LVGL8.1 ——anim 动画 (anim 16)
  9. Microsoft Web Farm Framework (WFF) 2.0正式发布
  10. 中医大计算机考试题目,中医大计算机复习题-20210319205538.docx-原创力文档