特性:
LinkedList类继承AbstractSequentialList接口,底层数据结构为双链表,数据有序性;可添加多个null值。方法:增加:add(E e)默认尾部添加 、 addFirst头加 、 addLast尾加;删除:remove(Object o)值删除 、 removeLast尾删 、 removeFirst头删。
下面我们实现一个简单的LinkedList类
public class LinkedList{
public class Entry<T> {
private T value;
private Entry<T> next; //后继
private Entry<T> pre; //前驱
public Entry(){ //申请头节点
next = null;
pre = null;
}
public Entry (T value){ //申请普通节点
this.value = value;
this.next = null;
this.pre = null;
}
public T getValue() { return value; }
public void setValue(T value) {this.value = value; }
public Entry<T> getNext() {return next;}
public void setNext(Entry<T> next) { this.next = next; }
public Entry<T> getPre() {return pre; }
public void setPre(Entry<T> pre) {this.pre = pre; }
}
private Entry<E> headNode;
public LinkedList(){
headNode = new Entry<E>();
}
// 头部添加
public void addHead(E value){
Entry<E> entry = new Entry<E>(value);
entry.setNext(headNode.getNext());
headNode.setNext(entry);
entry.setPre(headNode);
if(entry.getNext() != null) { //防止空指针异常
entry.getNext().setPre(entry);
}
}
// 获取尾部元素
public Entry<E> getTailEntry(){
Entry<E> p = null;
for( p= headNode;p.getNext()!= null;p = p.getNext()){
}
return p;
}
// 尾部添加
public void addTail(E value){
Entry<E> entry = new Entry<E>(value);
Entry<E> tail = getTailEntry();
tail.setNext(entry);
entry.setPre(tail);
}
/**
* 给第pos个位置添加一个value节点(不算头节点)
* @param pos
* @param value
*/
public void add(int pos,E value){
if(pos<0){
return;
}
Entry<E> newEntry = new Entry<E>(value);
int count = 0;
for(Entry<E> entry = headNode.getNext();entry != null;entry = entry.getNext()){
count++;
if(count == pos){
Entry<E> beforeEntry = entry.getPre();
//next域更新
beforeEntry.setNext(newEntry);
newEntry.setNext(entry);
//pre域更新
entry.setPre(newEntry);
newEntry.setPre(beforeEntry);
}
}
}
// 头部删除
public boolean deleteHead(){
if(headNode.getNext()==null){
return false;
}
Entry<E> afterHead = headNode.getNext();
headNode.setNext(afterHead.getNext()); //头节点next域直接指向头节点后一个的后一个
if(afterHead.getNext() != null) {
afterHead.getNext().setPre(headNode);
}
afterHead.setValue(null); //防止内存泄漏
return true;
}
// 尾部删除
public boolean deleteTail(){
if(headNode.getNext()==null){
return false;
}
Entry<E> tail = getTailEntry();
Entry<E> beforeTail = tail.getPre(); //得到尾节点的前驱
beforeTail.setNext(null); //前驱next域置空
tail.setValue(null); //防止内存泄漏
return true;
}
/**
* 删除第pos个位置的节点
* @param pos
*/
public void delete(int pos){
if(pos < 0){
return;
}
int count = 0;
for(Entry<E> p = headNode.getNext();p != null;p = p.getNext()){
count++;
if(count == pos){
Entry<E> beforePos = p.getPre();
beforePos.setNext(p.getNext());
if(p.getNext() != null){
p.getNext().setPre(beforePos);
}
p.setValue(null);
}
}
}
//根据value删除元素
public void deleteValue(E value){
for(Entry<E> p = headNode.getNext();p!=null;p = p.getNext()){
if(p.getValue().compareTo(value) == 0){
Entry<E> beforePos = p.getPre();
beforePos.setNext(p.getNext());
if(p.getNext() != null){
p.getNext().setPre(beforePos);
}
p.setValue(null);
}
}
}
public void show(){
for(Entry<E> p = headNode.getNext();p != null;p = p.getNext()){
System.out.print(p.getValue()+" ");
}
System.out.println();
}
}
ArrayList类和LinkedList类的区别:
1.底层数据结构不同,ArrayList:数组,LinkedList:双链表;
2.随机访问:ArrayList根据index下标直接访问,时间复杂度O(1);LinkedList根据value访问,时间复杂度O(n);
3.插入或删除:ArrayList涉及到剩余元素移动,LinkedList直接操作next域。特别地,在列表末尾增加一个元素两者所花的开销都是固定的。