LinkedList底层实现,及和ArrayList区别

特性:

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域。特别地,在列表末尾增加一个元素两者所花的开销都是固定的。

猜你喜欢

转载自blog.csdn.net/qq_43527426/article/details/86545254