本节总结下链表的底层实现,与动态数组的方法基本一致,可以在其做为底层的情况下实现链栈,链队等数据结构
为了后续操作方面起见,设置了虚拟头结点,在removeFirst以及addLast操作上逻辑比较好写
采用私有内部类Node为基本存储结构,内含多种构造方法,使用起来得心应手
private class Node {
public E e;
public Node next;
/**
* 创建一个结点,并且可以赋予他的后继
* @param e
* @param next
*/
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
以及初始化链表的时候增加了虚拟头结点
private Node dummyHead;
private int size;
/**
* 初始化链表,默认含有虚拟头结点
* 内不放置任何信息,方便后续操作
*/
public LinkedList() {
dummyHead = new Node(null, null);
size = 0;
}
在添加操作上使用了简单快捷的构造方法,首先找到要插入位置的前一个位置,在添加的数据的时候首先使新添加的结点指向后一个,并赋予上前一个结点的next域,有了基本的add,就可以方便的写出addLast和addFirst
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed , Illegal index");
}
Node prev = dummyHead;
//多遍历了虚拟头结点
for (int i = 0; i < index; i++) {
prev = prev.next;
}
prev.next = new Node(e, prev.next);
size++;
}
/**
* 在链表头部添加新的元素
*
* @param e
*/
public void addFirst(E e) {
add(0, e);
}
public void addLast(E e) {
add(size, e);
}
删除操作与添加有类似的操作就是始终有一个引用指向要删除或者添加位置的前一个位置
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Remove failed , Illegal index");
}
//prev需要指到要删除元素的前一个结点
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
Node retNode = prev.next;
prev.next = retNode.next;
//将此结点与链表脱离关系
retNode.next = null;
size--;
return retNode.e;
}
/**
* 从链表中删除元素e
*
* @param e
*/
public void removeElement(E e) {
Node prev = dummyHead;
while (prev.next != null) {
//prev需要指向要删除结点的前一个
if (prev.next.e.equals(e)) {
break;
}
prev = prev.next;
}
//判断条件为true说明该元素存在
if (prev.next != null) {
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size--;
}
}
public E removeFirst() {
return remove(0);
}
public E removeLast() {
return remove(size - 1);
}
最后当然不忘测试下啦:
public class Main { public static void main(String[] args) { LinkedList<Integer> linkedList = new LinkedList<Integer>(); for (int i = 0; i < 10; i++) { linkedList.addFirst(i); System.out.println(linkedList); } linkedList.add(2, 66); System.out.println(linkedList); linkedList.remove(2); System.out.println(linkedList); linkedList.removeLast(); System.out.println(linkedList); } }