与单链表上的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。
package com.data.tree;
//双向链表 作者廖敏
public class LinkList<E> {
// 定义单链表头用于标示第一个元素
private transient ELinkList<E> head = new ELinkList<E>(null, null, null);
// 定义单链表长度
public transient int size = 0;
// 添加第一个元素
public void addFirst(E ele) {
// 实例化链表元素
ELinkList<E> temp = new ELinkList<E>(ele, null, null);
// 如果没有第一个元素 添加第一个元素为temp
if (head.next == null) {
head.next = temp;
temp.previous = head;
// 存在第一个元素 当前元素的指向以前的一个元素 同时head指向当前元素
} else {
head.next.previous = temp;
temp.next = head.next;
temp.previous = head;
head.next = temp;
}
size++;
}
// 添加第一个元素
public void addLast(E ele) {
// 实例化链表元素
ELinkList<E> temp = new ELinkList<E>(ele, null, null);
// 获取最后一个元素 并且最后一个元素指向当前元素
ELinkList<E> e = getLastLink(null);
// 若果最后一个元素不存在 就是没哟一个元素
if (e == null)
addFirst(ele);
else {
e.next = temp;
temp.previous = e;
size++;
}
}
// 添加元素也是往第一个位置添加元素
public void add(E ele) {
addLast(ele);
}
// 删除第一个元素 判断第一个元素是否存在 如果存在 head指向第一个元素的下一个元素
public void removeFirst() throws Exception {
if (head.next != null) {
head.next = head.next.next;
size--;
} else {
throw new Exception("没有第一个元素");
}
}
// 删除某个元素 因为没有指针指向第一个元素 所以添加参数 前参 和当前参数
public boolean remove(E e, ELinkList<E> current) {
// 定义临时参数
ELinkList<E> currentlnk = null;
// 如果当前参数为null 当前参数就是 第一个元素 也就是head.next
// 前一个参数就是head
if (current == null) {
currentlnk = head.next;
// 如果有值则 使用当前值
} else {
currentlnk = current;
}
if (currentlnk.data.equals(e)) {
currentlnk.previous.next = currentlnk.next;
if (currentlnk.next != null)
currentlnk.next.previous = currentlnk.previous;
size--;
return true;
} else {
if (currentlnk.next == null)
return false;
return remove(e, currentlnk.next);
}
}
// 重第一个元素开始遍历找到并删除该元素
public boolean remove(E e) {
return remove(e, null);
}
// 是否为空
public boolean isEmpty() {
if (head.next != null)
return false;
return true;
}
// 获得首个元素
public E getFirst() {
if (head.next == null)
return null;
return head.next.data;
}
// 获取指定索引的值 一直next .next 就会根据次数去next 去的值
public E get(int index) throws Exception {
if (index + 1 > size) {
throw new IndexOutOfBoundsException("索引越界");
}
ELinkList<E> tmplnk = head;
for (int i = 0; i <= index; i++) {
tmplnk = tmplnk.next;
}
return tmplnk.data;
}
// 为了实现递归查询带的参数
public E getLast(ELinkList<E> link) {
ELinkList<E> next = null;
if (link == null)
next = head.next;
else
next = link;
if (next.next == null)
return next.data;
else
return getLast(next.next);
}
private ELinkList<E> getLastLink(ELinkList<E> link) {
ELinkList<E> next = null;
if (link == null)
next = head.next;
else
next = link;
if (next == null)
return null;
if (next.next == null)
return next;
else
return getLastLink(next.next);
}
// 获得最后一个元素
public E getLast() {
return getLast(null);
}
private class ELinkList<E> {
public E data;
public ELinkList<E> next;
public ELinkList<E> previous;
public ELinkList(E data, ELinkList<E> next, ELinkList<E> previous) {
this.data = data;
this.next = next;
this.previous = previous;
}
public ELinkList(E data) {
this(data, null, null);
}
}
}