用Java数据结构学习-线性表之顺序表
一、线性表的定义
线性表(linear list)简称表,是n(n≥0)个数据元素的有限序列,线性表中数据元素的个数称为线性表的长度。长度等于零的线性表称为空表,一个非空表如图2-4所示,通常记为:
L=(a1 ,a2,…",an)
其中,ai(l≤i≤n)称为数据元素,下角标i表示该元素在线性表中的位置或序号0,称元素ai位于表的第i个位置,或称ai是表中的第i个元素。a1称为表头元素,an 称为表尾元素,任意一对相邻的数据元素a-1和ai(1<i≤n)之间存在序偶关系<ai-1,ai>,且 ai-1称为ai的前驱,ai称为ai-1的后继。在这个序列中,元素a1,无前驱,元素an,无后继,其他每个元素有且仅有一个前驱和一个后继。
通俗一点讲,就是说。其实线性表可以装载一组数据的结构。表里第一个数据称为表头元素,最后一个数据称为表尾数据。表中数据都有一个前驱和后继。表头只有后继没有前驱,表尾只有前驱没有后继。
二、线性表用Java的抽象实现
线性表是一个灵活的数据结构,对线性表的数据元素可以进行存取访问、插入和删除等操作。我们可以用Java的将线性表的各个操作抽象成接口。将表要操作的数据定义为泛型,让其可以接受任意的数据类型。代码实现如下:
/**
* 线性表
* tip:Interface 默认添加 public abstract
*/
public interface ListInterface<T>{
/**
* 遍历列表
*/
void printList();
/*
* 返回列表长度
* */
int length();
/*
* 返回对应元素的位置
* */
int locate(T element);
/*
* 根据位置返回元素
* */
T getElement(int i);
/*
* 指定位置插入元素
* */
void insert(int i, T element);
/*
*是否为空
* */
boolean isEmpty();
/*删除节点*/
T remote();
/*添加节点*/
void add(T element);
}
三、线性表的顺序存储结构及实现(顺序表的实现)
1.线性表的顺序存储结构
一般来说,线性表有两种存储结。一种是顺序存储结构也称为顺序表,一种是链接存储结构称为链表。顺序存储结构的基本思想就是用一段连续的存储空间依次存储线性表的数据元素。在Java中需要用到连续的存储空间,我们可以用数组来模拟这种特征。
2.代码实现
前面我们定义了线性表的抽象接口,接下来我们就来实现线性表的第一种存储结构顺序表。我们首先定义一个SequentialList类,然后来实现我们上面定义线性表的抽象接口。代码如下:
import exceptions.ListExceptions;
/**
* @author Hognhu
* @Dataon 2020/10/25
*/
public class SequentialList<T> implements ListInterface<T>{
//当前长度
private int length;
//
private T[] list;
//默认容量一百
private final static int LISH_SIZE = 100;
public SequentialList(){
length = 0;
//初始化列表
list = (T [])(new Object[LISH_SIZE]);
}
/*有参初始化*/
public SequentialList(T[] initList,int n){
list = (T[])new Object[LISH_SIZE];
if(n>length || n<0)
throw new ArrayIndexOutOfBoundsException("列表太长了!");
length = n;
for(int i= 0 ; i<length ;i++)
list[i] = initList[i];
}
@Override
public void printList() {
if(isEmpty()){
System.out.println("列表为空!");
}else{
for(int i = 0;i<length;i++){
System.out.println(list[i]);
}
}
}
@Override
public int length() {
return this.length;
}
@Override
public int locate(T element) {
for(int i =0; i<length; i++)
if(element.equals(list[i]))
return i;
return -1;
}
@Override
public T getElement(int i) {
return list[i];
}
@Override
public void insert(int index, T element) {
if(length == list.length) throw new ListExceptions("数组达到最大容量!");
if(index<0 || index>length) throw new ListExceptions("位置错误!");
//数组移位
System.arraycopy(list, index, list, index + 1, length - index);
list[index] = element;
length++;
}
@Override
public boolean isEmpty() {
return length==0?true:false;
}
public T remote(int index){
if(length == list.length) throw new ListExceptions("数组达到最大容量!");
if(index<0 || index>length) throw new ListExceptions("位置错误!");
T oldValue = list[index];
//移位
if(length != 1)
System.arraycopy(list,index+1,list,index,length-(index+1));
list[--length] = null;
return oldValue;
}
@Override
public T remote() {
return remote(length-1);
}
@Override
public void add(T element) {
list[length++] = element;
}
}
需要说明的是,顺序表的增加,删除,查询,修改实际上都是对数组的操作。所以要时刻注意下标的界限,看看有没有越界操作数组。
其次我们在对数组里的第i个元素进行插入操作的时候,实际上我们是把从第i个开始的所有数组元素都往后移动了一位,为将要插入的元素挤出了一个位置。插入的时候要注意判断是否顺序表达到了最大容量,不然有可能会报数组越界错误。
如果删除第i个元素的话,我们是把从第i个后面的元素都往前移动一个单位,比如让第i个元素等于第i+1个元素,以此类推。后一个覆盖掉前一个,这样就相当我们删除了第i个数据元素。
四、结果演示
package exceptions;
import linearTable.SequentialList;
/**
* @author Hognhu
* @Dataon 2020/10/26
*/
public class Test2 {
public static void main(String[] args) {
SequentialList<Integer> sequentialList = new SequentialList<>();
System.out.println("isEmpty= "+sequentialList.isEmpty());
sequentialList.add(1);
sequentialList.add(2);
sequentialList.add(-3);
sequentialList.add(4);
sequentialList.printList();
System.out.println("isEmpty= "+sequentialList.isEmpty());
System.out.println("locate(3)= "+sequentialList.locate(4));
System.out.println("length= "+sequentialList.length());
//test Error
//System.out.println("length= "+link.remote(5));
}
}
测试结果:
五、其他辅助类
package exceptions;
/**
* @author Hognhu
* @Dataon 2020/10/26
*/
public class ListExceptions extends RuntimeException {
public ListExceptions(String message) {
super(message);
}
}
今天的总结就到此结束了,各位小伙伴有什么好主意,或者问题的话。欢迎在评论区交流哦????
上一篇: 数据结构学习二——顺序表