链表是数据结构中最基础的内容,链表在存储结构上分成两种:数组形式储存,链式存储。
相比c语言需要的结构体,在java中由于有了面向对象编程,将指针‘藏’了起来,不需要分配内存。
所以只需要创建一个对象数组,为了能让链表更加实用,方便存储非基本类型的对象,所以使用了泛型。
菱形运算符<>中放你自己写的或者基本类型,比如你创建了一个Stdent类,想用链表将很多学生的信息存起来。
就可以myArrayList a=new myArrayList();这个链表就都存Student类的对象了。
可以使用异常处理进一步优化。
- 链表接口
package 数据结构;
public interface List<E> {
//返回链表的大小,即数据元素的个数
public int getSize();
//判断链表是否为空
public boolean isEmploy();
//判断链表是否包含元素
public boolean contains(E val);
//头插
public boolean headadd(E val);
//尾插
public boolean tailadd(E val);
//返回数据元素在链表中的序号,若不存在返回-1
public int indexOf(E val);
//将数据元素插入到链表的i个位置,成功则返回true,失败false
public boolean insert(int i,E val);
//删除链表中序号为i的元素,成功则返回true,失败false
public boolean remove(int i) ;
//删除链表中第一个与元素相同的元素,成功true,失败false
public boolean remove(E val);
//替换链表中序号为i的元素
public void replace(int i,E val) ;
//返回链表中序号为i的元素
public Object getval(int i) ;
//输出链表
public void print();
}
- 用数组实现的链表
package 数据结构;
import java.util.Arrays;
//@Override:重写父类方法时用于检验
public class myArrayList<E> implements List<E> {
/**
* DEFAULT_SIZE 默认长度 单个数组最大长度
* element 存储元素的数组
* capacity 当前链表容量(为了扩容存在)
* size 当前数据个数
*/
private final int DEFAULT_SIZE = 8;
private Object[] element;
private int capacit;
private int size;
// 初始化链表
public myArrayList() {
element = new Object[DEFAULT_SIZE];
size = 0;
capacit = DEFAULT_SIZE;
}
myArrayList(E[] array){
if(array.length<=DEFAULT_SIZE) {
element=Arrays.copyOf(array, DEFAULT_SIZE);
size=array.length;
capacit=DEFAULT_SIZE;
}
else {
System.out.println("过长");
}
}
//获取数据当前数据个数
@Override
public int getSize() {
return size;
}
//判空
@Override
public boolean isEmploy() {
if(size==0)
return true;
else
return false;
}
//判满
public boolean isFull() {
if(size==capacit)
return true;
else
return false;
}
//是否含有val
@Override
public boolean contains(E val) {
for(int i=0;i<size;i++) {
if(element[i]==val)
return true;
}
return false;
}
//获取val的位置
@Override
public int indexOf(E val) {
for(int i=0;i<size;i++) {
if(element[i]==val)
return i;
}
return -1;
}
// 获取i位置的数据
@Override
public Object getval(int i) {
if(i>0&i<size)
return element[i];
return null;
}
//扩容
private void Expansion() {
capacit+=DEFAULT_SIZE;
element=Arrays.copyOf(element, capacit);
}
//头插
@Override
public boolean headadd(E val) {
if(isEmploy()) {
element[0]=val;
size++;
return true;
}
else if(!isFull()) {
for(int i=size;i>0;i--) {
element[i]=element[i-1];
}
element[0]=val;
size++;
return true;
}
else if(isFull()) {
Expansion();
headadd(val);
}
return false;
}
//尾插
@Override
public boolean tailadd(E val) {
if(!isFull()) {
element[size]=val;
size++;
return true;
}
else if(isFull()) {
Expansion();
tailadd(val);
}
return false;
}
//在i位置插入val
@Override
public boolean insert(int i, E val) {
if(i==0)
headadd(val);
if(i==size)
tailadd(val);
else if(i>0&&i<size) {
if(!isFull()) {
for(int j=size;j>i;j--) {
element[j]=element[j-1];
}
element[i]=val;
size++;
return true;
}
else if(isFull()){
Expansion();
insert(i, val);
}
}
return false;
}
//删除i位置的元素
@Override
public boolean remove(int i) {
if(!isFull()) {
for(int j=i;j<size;j++) {
element[j]=element[j+1];
}
size--;
return true;
}
else if(isFull()) {
for(int j=i;j<size-1;j++) {
element[j]=element[j+1];
}
element[size-1]=0;
size--;
return true;
}
return false;
}
//删除val
@Override
public boolean remove(E val) {
if(indexOf(val)!=-1) {
remove(indexOf(val));
}
return false;
}
//用val替换i位置的元素
@Override
public void replace(int i, E val) {
element[i]=val;
}
//输出链表
@Override
public void print() {
for(int i=0;i<size;i++)
System.out.print(element[i]+" ");
}
}
- 数组链表的实例
package 数据结构;
public class Main {
public static void main(String[] args) {
Integer[] a=new Integer[]{1,2,3,4};
myArrayList<Integer> AL=new myArrayList<>(a);
System.out.print(AL.getSize()+" "+AL.getval(1)+" "+AL.contains(3)+" "+
AL.indexOf(4)+" "+AL.isFull());
System.out.println();
AL.headadd(6);//6,1,2,3,4
AL.insert(2, 9);//6,1,9,2,3,4
AL.remove(4);//6,1,9,2,4
AL.replace(2, 5);//6,1,5,2,4
AL.print();
System.out.println();
String[] b=new String[] {"abc","qwe","olk"};
myArrayList<String> AL2=new myArrayList<>(b);
AL2.tailadd("wos");
AL2.remove("abc");
AL2.print();
}
}