这是第一篇博客,主要是从数据结构开始记录,以后会逐步补充之前的JAVA SE
线性结构的介绍
数据结构中线性结构指的是数据元素之间存在着"一对一"的线性关系的数据结构。
如(a0,a1,a2,…,an),a0为第一个元素,an为最后一个元素,此集合即为一个线性结构的集合。
线性表的分类
按照不同的存储方式,线性表分为“顺序表”和“链式表”。
顺序表
顺序表 是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。(来自百度)
通俗的说,顺序表是一段连续的数据元素储存在相邻的内存,所以顺序表的读取速度比较快。
链式表
链式表示指的是用一组任意的存储单元存储线性表中的数据元素,称为线性表的链式存储结构。它的存储单元可以是连续的,也可以是不连续的。在表示数据元素之间的逻辑关系时,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置),这两部分信息组成数据元素的存储映像,称为结点(node)。它包括两个域;存储数据元素信息的域称为数据域;存储直接后继存储位置的域称为指针域。指针域中存储的信息称为指针或链 。(来自百度)
顺序表的实现接口
/*
* list是线性表的最终父接口
*/
public interface List<E> {
/*
* 获取线性表中元素的个数(线性表的长度)
* @return 线性表中有效元素的个数;
*/
public int getSize();
/*
* 判断线性表是否为空
* @return 是否为空的布尔类型值
*/
public boolean isEmpty();
/*
* 在线性表中指定的index角标处添加元素e
* @param index 指定的角标0<=index<=线性表的有效长度
* @param e 要插入的元素
*/
public void add(int index,E e);
/*
* 在线性表的表头位置插入一个元素
* @param e 要插入的元素 指定在角标0处
*/
public void addFirst(E e);
/*
* 在线性表的表头位置插入一个元素
* @param e 要插入的元素 指定在角标size处
*/
public void addLast(E e);
/*
* 在线性表中获取指定index角标处的元素
* @param index 指定的角标0<=index<size
* @return 该角标所对应的元素
*/
public E get(int index);
/*
* 获取线性表中表头的元素
* @return 表头元素 index=0;
*/
public E getFirst();
/*
* 获取线性表中表头的元素
* @return 表头元素 index=size-1;
*/
public E getLast();
/*
* 修改线性表中指定index处的元素为新元素e
* @param index 指定的角标
* @param e 新元素
*/
public void set(int index,E e);
/*
* 判断线性表中是否包含指定元素e 默认从前往后找
* @param e 要判断是否存在的元素
* @return 元素的存在性布尔类型值
*/
public boolean contains(E e);
/*
* 在线性表中获取指定元素e的角标 默认从前往后找
* @param e 要查询的数据
* @return 数据在线性表中的角标
*/
public int find(E e);
/*
* 在线性表中删除指定角标处的元素 并返回
* @param index 指定的角标 0<=index<=size
* @return 删除掉的老元素
*/
public E remove(int index);
/*
*删除线性表中的表头元素
*@return 表头元素
*/
public E removeFirst();
/*
*删除线性表中的表尾元素
*@return 表尾元素
*/
public E removeLast();
/*
* 在线性表中删除指定元素e
*
*/
public void removeElement(E e);
/*
* 清空线性表
*/
public void clear();
}
顺序表的方法
创建顺序表(创建数组)
public class ArrayList<E> implements List<E> {
private E[] data; //存储数据元素的容器
private int size; //线性表的有效元素的个数
//data.length 表示线性表的最大容量Capacity
private static int DEFAULT_SIZE = 10; //容器的默认容量
/*
* 创建一个容量默认为10的一个线性表
*/
public ArrayList() {
this(DEFAULT_SIZE);
}
/*
* 创建一个容量为指定capacity的一个线性表
*/
public ArrayList(int capacity) {
this.data=(E[])new Object[capacity];
this.size=0;
}
/*
* 将一个数组封装成线性表
*/
public ArrayList(E[] arr) {
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
增加数据元素
@Override
public void add(int index, E e) {
if(index<0||index>size) {
throw new ArrayIndexOutOfBoundsException("add函数角标越界");
}
//判断是否已满
if(size==data.length) {
resize(2*data.length);
}
for(int i = size-1;i>=index;i--) {
data[i+1]=data[i];
}
data[index]=e;
size++;
}
/*
* 改变data的长度(扩容,缩容)
* @param 新数组的长度
*/
private void resize(int newlen) {
E[] newData = (E[])new Object[newlen];
for(int i=0;i<size;i++) {
newData[i]=data[i];
}
data = newData;
}
@Override
public void addFirst(E e) {
add(0,e);
}
@Override
public void addLast(E e) {
add(size,e);
}
删除数据元素
@Override
public E remove(int index) {
if(index<0||index>size-1) {
throw new ArrayIndexOutOfBoundsException("remove函数角标越界");
}
E e=get(index);
for(int i =index+1;i<=size-1;i++) {
data[i-1]=data[i];
}
size--;
//判断是否缩容
//1.最短不能缩过默认容量
//2.有效元素的个数小于等于容量的1/4
if(size <= (data.length/4) && data.length > DEFAULT_SIZE) {
resize(data.length/4);
}
return e;
}
@Override
public E removeFirst() {
return remove(0);
}
@Override
public E removeLast() {
return remove(size-1);
}
@Override
public void removeElement(E e) {
int index=find(e);
if(index==-1) {
throw new IllegalArgumentException("删除元素不存在");
}
remove(index);
}
清空顺序表
@Override
public void clear() {
size = 0;
}