java链表底层采用对象存储,优点,插入方便。缺点查询速度慢。
直接上代码。
public class MyLinkedList<E> {
private int size; // 链表长度
private Node<E> first; // 头
private Node<E> last; // 尾
public void add(E e) {
Node<E> l = last; // 临时保存原尾
Node<E> node = new Node<>(l, e, null);
last = node;
if (first == null) {
first = node;
} else {
// 原尾的下一个指针指向当前插入元素
l.next = node;
}
size++;
}
/**
* 指定位置插入节点
*
* @param index
* @param e
*/
public void add(int index, E e) {
rangeCheck(index);
Node<E> oldNode = getNode(index); // 原节点
Node<E> oldNodePrev = oldNode.prev; // 原节点上一个节点
Node<E> newNode = new Node<>(oldNodePrev, e, oldNode);
oldNode.prev = newNode;
if (oldNodePrev == null) {
first = newNode;
} else {
oldNodePrev.next = newNode;
}
size++;
}
/**
* 根据位置删除节点
*
* @param index
* @return
*/
public E remove(int index) {
rangeCheck(index);
Node<E> node = getNode(index);
if (node != null) {
Node<E> prev = node.prev;// 获取删除节点的上节点
Node<E> next = node.next;// 获取删除节点的下节点
if (prev == null) {
first = next;
} else {
prev.next = next;
// 置为空方便jvm删除
node.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
node.next = null;
}
size--;
// 置为空方便jvm删除
node.item = null;
return node.item;
}
return null;
}
/**
* 根据对象删除元素
*
* @param o
* @return
*/
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
remove(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
remove(x);
return true;
}
}
}
return false;
}
public int size() {
return size;
}
/**
* 根据位置获取删除对象
*
* @param index
* @return
*/
public E get(int index) {
rangeCheck(index);
Node<E> node = null;
// 二分查找
if (index < (size << 1)) {
node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
} else {
node = last;
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
}
return node.item;
}
public Node<E> getNode(int index) {
Node<E> node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
/**
* 构造函数赋值
*
* @param prev
* @param element
* @param next
*/
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
private void rangeCheck(int index) {
if (index > size || index < 0) {
throw new IndexOutOfBoundsException("size:" + size + "index+" + index);
}
}
}