zoukankan      html  css  js  c++  java
  • Java基础---LinkList

    一. 描述

          双向链表(Doubly-linked)实现了接口List和Deque(双端队列),实现了所有的list操作并允许元素可为null。

            对于双向链表,所有的操作都符合预期。索引到列表的操作将从列表头或者列表尾开始遍历列表,以便更接近指定的索引为准。(不支持类似数组的随机访问,根据下标访问链表的话,需要从链表头或者链表尾开始遍历。)

      与ArrayList一样,此实现不是同步的。如果有多个线程访问同一个链表的话,并且至少上一个线程在结构上修改了链表,他必须对外同步。(结构修改是指r任何操作添加或者删除多个元素,仅仅设置元素值不是修改。)。这通常是在某些对象上的同步完成封装的。如果不存在这样的对象,则应该使用java.util. Collections.synchronizedList(new LinkedList(....))。

      快速失败,在ArrayList已经介绍了。

    二. 结构

       LinkedList内部元素采用Node,链表来实现。代码如下,可以发现这是一个私有的内部类,导致我们无法直接获取Node,只能获取Node的值。

    private static class Node<E> {
            E item;
            Node<E> next;
            Node<E> prev;
    
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
            }
        }

      这个就导致了一个很经典的面试问题,for循环遍历LinkedList为什么比遍历数组慢。原因:主要原因for循环遍历LinkedList我们无法获取Node类,无法获取节点属性的next(下一个节点),如果可以获取的话,那么我们从头部或者尾部遍历都是很快的。那么我们就只能通过下标去访问了,数组支持随机访问,根据下标访问的需要的时间复杂度O(1);而我们看下LinkedList的下标访问返回的是值,不是节点,我们无法获取到当前节点,也就无法获取下一个节点。

    public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
    }

      接下来,我们继续查询获取节点的算法,我们发现根据下标来获取Node节点,需要从第一个节点或者最后一个节点遍历,直到到达下标的地方,这样时间复杂度最多需要O(2/n),由此可见for循环遍历效率比较低。那么迭代器为啥可以比较快呢,因为迭代器可以直接访问节点...还有下个节点,代码如下:

    Node<E> node(int index) {
        // assert isElementIndex(index);
    
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
    

      那么结论来了:linkedList底层是链表实现,(1)下标随机访问链表,通过分析get方法,算法要求从头或者从尾依次访问节点,直到达到指定的节点,并且返回的是值而不是节点对象。(2)由于返回的是节点对象,我们无法直接获取节点对象的下一个对象地址,只能再通过get方法,再走一遍1的流程。(3)iterator可以访问节点,可以获取当前节点的下个节点,时间复杂度o(1)

  • 相关阅读:
    14 微服务电商【黑马乐优商城】:day02-springcloud(理论篇一:HttpClient的简单使用)
    14 微服务电商【黑马乐优商城】:day01-springboot(Thymeleaf快速入门)
    14 微服务电商【黑马乐优商城】:day01-springboot(理论篇)
    1.1 行列式:二阶三阶n阶行列式
    ubuntu:make工程管理器大致了解
    ubuntu:VIM使用
    机器学习:朴素贝叶斯邮件分类(python实现)
    ubuntu 添加快速启动
    ubuntu:软件包
    Ubuntu:远程管理ubuntu文件系统
  • 原文地址:https://www.cnblogs.com/knsbyoo/p/14071602.html
Copyright © 2011-2022 走看看