线性表

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

举个例子:一个班的小朋友,一个跟着一个排队,当中的每个小朋友都知道他前面的是谁,后面的是谁,如同一根线把他们串联起来。就可以称之为线性表。

给了线性表的定义,分析一下线性表写哪些什么操作,从属性和行为两个方面分析:

属性方面:

int size 线性表的有效元素个数

int capacity 线性表的最大容量

E[] data 数据的存储容器

行为方面

  • 增()
  • 删()
  • 改()
  • 查()
  • 其他()

线性表顺序存储结构的定义指的是用一段地址依次存储线性表的数据元素。顺序存储结构可以基于动态数组来实现,用Java语言实现线性表顺序存储结构,线性表的抽象数据类型我们定义为接口List,基本内容如下:(其中的方法都是抽象的,有public abstract,这里我们省略了)

/*

定义线性表的接口List

List支持泛型E

该List线性表中所存储的具体数据类型由外界决定

*/

public interface List extends Iterable{ //接口继承Iterable为实现迭代器

//获取线性表中元素的有效个数

public abstract int getSize();

//判断线性表是否为空

boolean isEmpty();

//在线性表指定index角标处出入元素e

void add(int index,E e);

//在线性表的表头插入元素e

void addFirst(E e);

//在线性表的表尾插入元素e

void addLast(E e);

//获取线性表中指定角标index处元素

E get(int index);

//获取表头元素

E getFirst();

//获取表尾元素

E getLast();

//修改线性表中指定角标index处的元素为新元素e

void set(int index,E e);

//判断线性表中是否包含元素e

boolean contains(E e);

//查找元素e的角标(从左到又默认第一个出现的元素角标)

int find(E e);

//删除并返回线性表中指定角标index处的元素

E remove(int index);

//删除并返回表头元素

E removeFist();

//删除并返回表尾元素

E removeLast();

//删除指定元素e

void removeElement(E e);

//清空线性表

void clear();

}

接下来写线性表顺序存储结构ArrayList,让它实现接口List

import java.util.Iterator;

/*

创建线性表的顺序存储结构实现类ArrayList

*/

public class ArrayList implements List{

//创建E类型的一维数组

private E[] data;

//维护元素的个数

private int size;

//默认最大容量为10

private static int DEAFULT_CAOACITY=10;

//创建一个默认大小的顺序表

public ArrayList(){

//data =(E[]) (new Objects[DEAFULT_CAOACITY]);

//调用一个参数的构造函数传参

this(DEAFULT_CAOACITY);

}

//创建一个容量由用户指定的顺序表

public ArrayList(int capacity){

if(capacity<=0){

//没捕获没声明,运行异常,创建异常对象,抛出

throw new IllegalArgumentException("容量必须>0"+capacity);

}

//对一维数组data进行初始化,类型给Object再强转为E泛型

data=(E[])(new Object[capacity]);

//有效元素个数初始为0

size=0;

}

//用户传入一个数组,将该数组封装成一个顺序表

public ArrayList(E[] data){

if(data==null){

throw new IllegalArgumentException("数组不能为空");

}

this.data=(E[])(new Object[data.length]);

//读取传入数组元素,放入data

for(int i=0;i

this.data[i]=data[i];

}

//并更新有效元素个数

size=data.length;

}

//重写接口中的获取有效元素个数

@Override

public int getSize() {

//直接返回成员变量size

return size;

}

//重写判空方法

@Override

public boolean isEmpty() {

return size==0;

}

@Override

public void add(int index,E e) {

if(index<0||index>size){ //角标index越界的情况

throw new IllegalArgumentException("角标越界");

}

//如果线性表满了就扩容

if(size==data.length){

//扩容(扩二倍)

resize(data.length*2);

}

//插入元素

for(int i=size;i>index;i--){ //后移元素

data[i]=data[i-1];

}

data[index]=e; //把元素插到index位置

//有效元素个数更新

size++;

}

//扩缩容函数

private void resize(int newLength) {

//创建新数组

E[] newData=(E[])(new Object[newLength]);

for(int i=0;i

newData[i] = data[i]; //元素放入新数组

}

//偷梁换柱

data = newData;

}

@Override

public void addFirst(E e) {

//表头插入元素,调用add,角标传0即可

add(0,e);

}

@Override

public void addLast(E e) {

//表尾插入元素,调用add,角标传size即可

add(size,e);

}

//重写获取线性表中指定角标index处的元素的方法

@Override

public E get(int index) {

if(isEmpty()){ //判空,为空时不能获取元素

throw new IllegalArgumentException("线性表为空");

}

if(index<0||index>=size){ //输入角标越界情况,抛异常

throw new IllegalArgumentException("角标越界");

}

return data[index];

}

@Override

public E getFirst() {

//获取表头,调用get方法,index给0

return get(0);

}

@Override

public E getLast() {

//获取表头,调用get方法,index给size-1

return get(size-1);

}

//重写修改线性表中指定角标index处的元素为新元素e的方法

@Override

public void set(int index, E e) {

if(isEmpty()){

throw new IllegalArgumentException("线性表为空");

}

if(index<0||index>=size){

throw new IllegalArgumentException("角标越界");

}

data[index]=e; //把元素e给角标index对应位置

}

//重写 判断线性表中是否包含元素e

@Override

public boolean contains(E e) {

//调用find方法,能找到就包含

return find(e)!=-1;

}

//重写 查找元素e的角标

@Override

public int find(E e) {

if(isEmpty()){ //判空 抛异常

throw new IllegalArgumentException("线性表为空");

}

//遍历表中元素,与e对比,比的是内容

for(int i=0;i

if(data[i].equals(e)){ //data里面都是对象 ==比的是地址 equals比的是内容

return i;

}

}

return -1;

}

//重写 删除并返回线性表中指定角标index处的元素

@Override

public E remove(int index) {

if(isEmpty()){ //表为空时,不可删除

throw new IllegalArgumentException("线性表为空");

}

if(index<0||index>=size){

throw new IllegalArgumentException("角标越界");

}

//把index处元素给变量ret,用于返回

E ret = data[index];

//把后面的元素前移

for(int i=index+1;i

data[i-1]=data[i];

}

//并将有效元素个数递减

size--;

//缩容的情况,条件是自定义

if(size<=data.length/4&&data.length/2>=10){ //如果有效长度小于等于现在长度的1/4,同时缩容之后的长度大于等于10,才可以缩容

resize(data.length/2);

}

//返回被删除元素

return ret;

}

@Override

public E removeFirst() {

//删表头,调用remove方法

return remove(0);

}

@Override

public E removeLast() {

//删表尾

return remove(size-1);

}

//重写 删除指定元素e

@Override

public void removeElement(E e) { //从左到右删第一个

//先找到e,拿到角标

int index = find(e);

//如果角标存在

if(index!=-1){

//调用remove方法删除元素

remove(index);

}else{ //否则抛出异常

throw new IllegalArgumentException("元素不存在");

}

}

//重写 清空线性表方法

@Override

public void clear() {

//把构造函数内容拿来用

size=0;

data=(E[])(new Object[DEAFULT_CAOACITY]);

}

//ArrayLis特有的方法 获取线性表容量

public int getCapacity(){

return data.length;

}

//toString方法

/*打印这样的格式

ArrayList:10/20

[]

*/

public String toString(){

//创建StringBuilder对象,不需要额外创字符串,在原来的上加字符

StringBuilder sb = new StringBuilder();

sb.append(String.format("ArrayList: %d/%d ",size,data.length));

//用数组的形式输出

sb.append('[');

if(isEmpty()){ //若为空,打印 []

sb.append(']');

}else{ //不为空,遍历线性表元素

for(int i=0;i

//在原来上加字符

sb.append(data[i]);

if(i==size-1){ //遍历到最后一个元素打印']'

sb.append(']');

}else{ //不然在每个元素中间打','

sb.append(',');

}

}

}

//调用对象的tostring方法返回对象

return sb.toString();

}

//返回当前数据结构的一个迭代器对象

//迭代器用于在没有角标支持的环境下遍历元素

@Override

public Iterator iterator() {

return new ArrayListIterator(); //创建并返回内部类对象

}

//迭代器 内部类

private class ArrayListIterator implements Iterator{ //

//index初始为-1

private int index=-1;

@Override

public boolean hasNext() {

return index

}

@Override

public E next() {

index++;

return data[index];

}

}

}

写完可以写一个测试类测试一下各个方法的正确性。

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

  1. node 获取表单数据 为空_程序员:数据结构和算法,中序线索化二叉树

    1.中序线索化二叉树   创建如上的二叉树,线索化二叉树时,根据指定的遍历方式得到的节点的访问顺序,一个节点前面的节点,叫做前驱节点,一个节点后面的节点,叫做后继节点.   线索化二叉树的规则:   ...

  2. 数据结构与算法-2-链表的基本操作-查找

    数据结构与算法-2-链表的基本操作-查找(c语言) 本文是单链表的C语言实现方法,包括单链表的创建.插入.删除.修改.查找等基本操作. 链表结点的类型定义 /*链式存储结构的头结点*/ typedef ...

  3. 数据结构与算法-4-链表的基本操作-增

    数据结构与算法-4-链表的基本操作-增 注意:以下为顺序存储结构实现 相关的头文件 /*以下为头文件SqList.h是用于定义相关函数的头文件*/ #pragma once #define LIST_ ...

  4. 计算机编程概率论,程序员的数学:线性代数和概率统计

    程序员的数学:线性代数和概率统计 语音 编辑 锁定 讨论 上传视频 <程序员的数学:线性代数和概率统计>是2018年9月1日机械工业出版社出版的图书,作者是[美] 欧内斯特 戴维斯 .[1 ...

  5. 程序员必会英语词汇表

    程序员必会英语词汇表 A abstract 抽象的 abstract base class (ABC)抽象基类 abstract class 抽象类 abstraction 抽象.抽象物.抽象性 ac ...

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

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

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

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

  8. Java版数据结构与算法——线性表

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  9. 头歌-数据结构与算法 - 线性表

    第1关:实现一个顺序存储的线性表 #include <stdio.h> #include <stdlib.h> #include "Seqlist.h" S ...

最新文章

  1. resultType 与resultMap 的区别
  2. Ubuntu 16.04安装XMind 8
  3. Alpha 冲刺 (10/10)
  4. 手机上图片信息怎么拉一个矩形框_跟着黑鲨手机发布会学习PPT制作
  5. 通过管道传输快速将MySQL的数据导入Redis(自己做过测试)
  6. C# 系统应用之使用Pancel控件同一窗体切换页面
  7. Ryu oslo学习总结
  8. babel6和babel7中关于polyfill和preset-env和babel-plugin-transform-runtime等总结
  9. 南岸焊接机器人厂_严选原料,机器人焊接,探秘能达到奔驰标准的亿利生产线...
  10. docker 安装wordpress
  11. 统计标点符号的次数 java_Java实现统计一篇文章中每个单词出现的次数
  12. 杨奇龙 mysql 分区_MySQL Group Replication 入坑指北 | By杨奇龙
  13. 用python画折线图
  14. vb红绿灯交通灯小程序
  15. 汇川H5U PLC通过EtherCAT总线控制SV660N和X3E伺服
  16. 极客星球 | Unity3D插件模板化探索
  17. Validation 全注解+使用示例+官方文档
  18. 排序算法系列:归并排序算法
  19. 像素鸟html代码,flappy-bird方块版(用小方块替代像素鸟)
  20. 2020中北大学计算机调剂名额,2020年中北大学考研调剂安排

热门文章

  1. JDBC连接MySQL数据库:建立SSL连接出现警告信息
  2. 【BZOJ2437】【codevs1949】兔兔与蛋蛋游戏,博弈+二分图匹配
  3. 【英语学习】【Level 07】U01 Making friends L5 A friend for a day
  4. 【英语学习】【WOTD】links 释义/词源/示例
  5. 【英语学习】【Daily English】U04 Neighborhood L02 Would you mind if I used your ladder for a second?
  6. Intel Core Enhanced Core架构/微架构/流水线 (15) - 先进智能缓存
  7. windows模拟微信小程序_Windows 版微信新版本内测!小程序可以直接添加到电脑桌面了...
  8. 如何快速开发一个支持高效、高并发的分布式ID生成器(一)
  9. linux从usb安装软件,Linux下USB Camera的安装和使用
  10. 二进制(1):无符号编码和补码编码