一、链表的结构
1)顺序表
这是Java中线性表(顺序表)的结构图,他们排列紧密,在内存中一个挨着一个,这和我们数组的结构正好对应,因此我们可以使用 数组 来实现线性表。
2)链表
但链表就有所不同了,他们在内存中随机摆放,各自互不相连,所以我们没办法直接使用数组进行存储了
2.1)链表与结点
图中这一整个块,我们称其为结点,在每个结点,都有一个数据存放区,我们这里存了一个A,和一个地址存放区,通常存放着下一个结点的位置,因此我们使用了类与对象来实现链表
2.1.1)利用代码创建结点
首先我们创建一个Node类,代表结点
public class Node {
private Object Data;
//存放数据,因为我们可以存各种类型,所以我们创建一个Object类型的变量,Object是所有类的父类
private Node next;
//存放下个结点位置,由于下个结点还是结点类型的,所以我们创建一个Node类型的变量
public Node(Object data, Node next) {
Data = data;
this.next = next;
}
public Object getData() {
return Data;
}
public void setData(Object data) {
Data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
这样一个结点类就创造完成了,现在为了这些结点组合起来,形成链表,就该创建一个链表类了
2.1.2)利用代码创建链表
1)创建框架
public class MyLinkedList {
Node first;//头指针
Node last;//尾指针
int index = 0;//记录下一个结点的位置
}
首先我们创建一个Node类型的first变量和一个node类型的last变量,分别代表链表的第一个结点(头结点)和最后一个结点(尾结点),然后又创建了一个int类型的index变量,在这里我们代表下一个结点所在的位置
2)添加数据
在链表类建好后,我们需要写一个添加数据的方法
public class MyLinkedList {
Node first;
Node last;
int index = 0;
public void addData(Object data){
Node node = new Node(data,null);
if(first == null){
first = node;
last = node;
}else {
last.setNext(node);
last = node;
}
index++;
}
}
现在我们来看addData方法,为了向其添加数据,所以我们需要一个Object类型的变量data来接收各种数据
之后我们创建了一个新的结点,里面存入刚刚传进来的数据,因为我们是新添加的结点,因此没有下一个结点,所以它的next值我们存入null,代表没有下个结点
然后我们对first变量进行判断,因为first变量类型为引用类型的Node,因此我们如果没向其赋值,它的默认初值就是null。所以如果first==null成立,就代表我们正在添加第一个结点,因为是第一个,所以目前肯定也是整个链表里的最后一个数据,所以我们就直接把node赋给first和last,然后让index++即可。
这时,如果我们再添加一个元素,first中已经有值,所以first==null必定为假,我们就直接再把新的结点添加到最后一个结点的后面即可,那么怎样添加呢?
因为last代表的就是最后一个结点,因此last的下个结点自然就是最后的结点后面的结点,所以我们直接将新的结点赋给last的next变量即可: last.setNext(node);
然后最后的结点就变成了新添加进来的那个结点了,所以我们还要让last的值做出改变,让它成为新的last: last = node;
当然因为添加了新的数据,所以index的值别忘了改变。
因为无论所添加的值是不是第一个元素,我们都要对index的值进行改变,所以我们把index放在if分支结构的外面,这样无论如何都能执行到index++操作,而不用再分支内写两遍