zoukankan      html  css  js  c++  java
  • LinkedList集合

    数组特征:连续性、查询快(底层使用下标)、有序。

    数据删除原理:把要删除的元素后面的数据向前移动一位,将最后的一个元素置空(null)。

    指定下标原理:把要插入的元素的数据及后边的元素向后移动一位,然后将新插入元素覆盖之前下标位置的元素。

    链表分为:单向链表、双向链表,头和尾、节点(node)。

    节点包含:节点内容、下一个节点内容(nextNode)、上一个节点内容(preNode)。

    单向链表与双向链表的区别

    LinkeList原理

    LinkedList 和 ArrayList 一样,都实现了 List 接口,但其内部的数据结构有本质的不同。LinkedList 是基于链表实现的(通过名字也能区分开来),所以它的插入和删除操作比 ArrayList 更加高效。但也是由于其为基于链表的,所以随机访问的效率要比 ArrayList 差。

    LinkeList源码分析

    transient int size = 0;

    /**
    * Pointer to first node.
    * Invariant: (first == null && last == null) ||
    * (first.prev == null && first.item != null)
    */
    transient Node<E> first;

    /**
    * Pointer to last node.
    * Invariant: (first == null && last == null) ||
    * (last.next == null && last.item != null)
    */
    transient Node<E> last;

    first作用:目的是为了查询,从哪里开始(first)到哪里结束(下标结束)
    last作用: 目的是为了添加元素,因为添加元素要从尾部开始,除了指定添加元素的下标位置。
    添加原理:在last节点后继续添加元素。
    查询原理:默认从first开始进行next查询。

    LinkedList数据结构原理

    LinkedList底层的数据结构是基于双向循环链表的,且头结点中不存放数据,如下: 

    既然是双向链表,那么必定存在一种数据结构——我们可以称之为节点,节点实例保存业务数据,前一个节点的位置信息和后一个节点位置信息,如下图所示: 

    数组和链表结构对比

     

    数组 是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少插入和删除元素,就应该用数组。

    链表 中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储 数据元素 的 数据域,另一个是存储下一个结点地址的 指针。

    如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表。

    内存存储区别

    数组从栈中分配空间, 对于程序员方便快速,但自由度小。

    链表从堆中分配空间, 自由度大但申请管理比较麻烦. 

    逻辑结构区别

    数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。 

    链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项) 

    总结

    1、存取方式上,数组可以顺序存取或者随机存取,而链表只能顺序存取; 

    2、存储位置上,数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定; 

    3、存储空间上,链表由于带有指针域,存储密度不如数组大; 

    4、按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n); 

    5、按值查找时,若数组无序,数组和链表时间复杂度均为O(1),但是当数组有序时,可以采用折半查找将时间复杂度降为O(logn); 

    6、插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可; 

    7、空间分配方面:

    数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败;

    链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;

    ArrayList查询速度快:可以通过下标查询,所以效率很高。

    LinkedList查询速度慢:因为LinkedList底层使用的是链表结构,链表没有下标,查询数据的时候需要一个个遍历查询所以导致查询效率慢(从first-->last)。

  • 相关阅读:
    如何将Oracle安装为Linux服务
    cp | mv | rm
    scp命令
    【读书笔记】深入理解计算机系统:第一章——计算机系统漫游
    微信小程序笔记(3):小程序的生命周期及其相关函数
    微信小程序笔记(2):wxml相比于html的扩展
    微信小程序笔记(1):小程序的代码构成和目录文件结构
    [C/C++]const限定符总结
    整数的表示与编码
    关于补码的由来和作用
  • 原文地址:https://www.cnblogs.com/ming-blogs/p/10903033.html
Copyright © 2011-2022 走看看