链表02--第四天

1.虚拟头结点

 1.1虚拟借点-node方法

 

/**
     * 获取index位置对应的节点对象
     * @param index
     * @return
     */
    private Node<E> node(int index) {
        rangeCheck(index);
        
        Node<E> node = first.next;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node;
    }
View Code

1.2虚拟节点-添加、删除

 

@Override
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        
        Node<E> prev = index == 0 ? first : node(index - 1);
        prev.next = new Node<>(element, prev.next);

        size++;
    }

    @Override
    public E remove(int index) {
        rangeCheck(index);
        
        Node<E> prev = index == 0 ? first : node(index - 1);
        Node<E> node = prev.next;
        prev.next = node.next;
            
        size--;
        return node.element;
    }
View Code

2.复杂度分析

数组   

数组的特点随机访问/随机存取(读取和修改)特别快

index*4+数组首地址

时间复杂度为o(1)

数组删除和添加的时间复杂度

O(n) 这个n不一定就是参数 而是数据规模

最好O(1)

最坏O(n)

平均O(n)

链表的随机访问/随机存取(读取和修改)的时间复杂度

最好O(1)

最坏O(n)

平均O(n)

链表

链表删除和添加的时间复杂度

最好O(1)

最坏O(n)

平均O(n)

链表的特点就是节省存储空间

 注意

有些资料说 链表的添加删除操作时间复杂度是O(1) 指的是添加删除那一瞬间操作

但是整体的时间复杂度仍然是O(n)

2.1数组的随机访问

 2.2动态数组、链表复杂度分析

 2.3动态数组add(E element)复杂度分析

注意

之前是 1+2+3+4+5+6+7+.....+n/n ==O(o)

现在是1+1+1+1+1+1+1+......+n/n==O(1)

 2.4动态数组的缩容

注意

出现复杂度震荡 就是当

扩容倍数和缩容时机只要不要相乘等于1就不会出现复杂度震荡

 

 3.双向链表

 3.1双向链表-只有一个元素

 3.2双向链表-node方法

 

    /**
     * 获取index位置对应的节点对象
     * @param index
     * @return
     */
    private Node<E> node(int index) {
        rangeCheck(index);
        
        if (index < (size >> 1)) {
            Node<E> node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        } else {
            Node<E> node = last;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }
View Code

3.3双向链表-add(int index,E element)

 

 

@Override
    public void add(int index, E element) {
        rangeCheckForAdd(index);

        // size == 0
        // index == 0
        if (index == size) { // 往最后面添加元素
            Node<E> oldLast = last;
            last = new Node<>(oldLast, element, null);
            if (oldLast == null) { // 这是链表添加的第一个元素
                first = last;
            } else {
                oldLast.next = last;
            }
        } else {
            Node<E> next = node(index); 
            Node<E> prev = next.prev; 
            Node<E> node = new Node<>(prev, element, next);
            next.prev = node;
            
            if (prev == null) { // index == 0
                first = node;
            } else {
                prev.next = node;
            }
        }
        
        size++;
    }
View Code

3.4双向链表-删除操作clearn()

java如何删除对象

1.看一个对象是否有引用

2.看这个引用是否是gc.root对象

2.1被栈(局部变量)指针指向的对象为gc.root对象

    @Override
    public void clear() {
        size = 0;
        first = null;
        last = null;
    }
View Code

猜你喜欢

转载自www.cnblogs.com/ggnbnb/p/12171091.html