对于单项链表,我们如果想在尾部添加一个节点,那么必须从头部一直遍历到尾部,找到尾节点,然后在尾节点后面插入一个节点。这样操作非常麻烦,并且耗费性能,如果我们在设计链表的时候多个对尾节点的引用,那么会简单很多。
双端链表相对于单向链表只是多了一个对尾部节点的引用
双端链表的实现与解析:
(1)创建双端链表
双端链表节点和单向链表一样分为两个部分,第一个部分保存或者显示关于节点的信息,另一个部分存储下一个节点的地址。最后一个节点存储地址的部分指向空(null),区别在于链表类中 不只是储存头部节点还储存了尾部节点
public class SingleLinkedList {
private int size; //节点个数
private Node head;//头节点
private Node tail;//尾节点
public SingleLinkedList(){
size = 0;
head = null;
tail = null;
}
class Node{
private Object data;// 每个节点的数据
private Node next;// 每个节点指向下一个节点的连接
public Node(Object data) {
this.data = data;
}
}
(2)添加节点
双端链表与单向链表主要区别就在添加链表是可以在尾部添加节点
添加头节点时若链表为空,尾节点也就要添加,尾节点等于头节点
只需要将当前插入的节点设置为头节点,next指向原头节点即可
//添加头节点
public void addHead(Object object) {
Node node = new Node(object);
if (size > 0) {
node.next = head;
}else{ //链表为空则尾节点等于头节点
tail = node;
}
head = node;
size++;
}
添加尾节点时若链表为空,头节点也就要添加,头节点等于尾节
只需要将尾节点的next设置为插入的节点,当前插入的节点设置为尾节点
//添加尾节点
public void addtail(Object object) {
Node node = new Node(object);
if (size > 0) {
tail.next = node;
}else{ //链表为空则尾节点等于头节点
head = node;
}
tail = node;
size++;
}
(3)删除节点
删除头部节点,当前链表为空时无法删除,当前链表为1时将头部节点和尾部节点指向空
若大于一只需要将当前插入的节点设置为头节点,next指向原头节点即可
//删除 头节点
public boolean delectHead() {
if (size == 0) {
return false;
}
if (head.next == null) {
head = null;
tail = null;
} else {
head = head.next;
}
size--;
return true;
}
接下来的操作都和单向链表一样。
扩展(闭环)
单向链表只是能向下访问,并且都只是从头到尾。
而闭环的思路是让他们头尾相连,也就是说我们只要在尾节点添加对头节点的引用,使其访问到尾节点时就继续访问到头节点,单向链表比作一条线,而闭环就是把这条线头尾相接成为一个环。