数据结构-链表结构分析(LinkedList)。

转载请注明作者:Edison丶梦楠

如有错误之处,还请您务必在留言区留下您的宝贵经验。或发送邮箱:mvpxiaonan@foxmail.com 告知。

本人非常感谢!希望能和您共同学习,共同进步!

下面介绍链表的两种结构:

单向链表:只能从头遍历到尾,或者从尾遍历到头。

图例:

next:获取下一个节点。

ele:每个节点中的元素。

first:指头部,链表中第一个元素。

我们可以理解为,当拿到链表对象,调用first()就可以得到第一个元素。

size:指元素的个数。(或链表的长度-1,索引从0开始),在集合中没有length一说。数组中的length相当于集合框架中的size

 

模拟代码为:

//单向链表 

class Node{
  Node next: //下一个节点 声明方法
  Object ele: //节点中的数据 声明方法

  public static void main(String [] Nodetest){
    Node cnode = new Node();
    cnode.next(); //获取下一个元素
    cnode.ele();  //获取当前节点元素。
    cnode.next().ele(); //获取下一个节点中的元素
}

}

 

双向链表:可以从头遍历到尾,也可以从尾遍历到头。

我们可以理解为,双向链表其实就是两个单向链表的合成。只不过是一个从头到尾,一个从尾到头。

 

图例:

 

prev:表示上一个节点

Node first:拿到第一个节点

Node last:拿到最后一个节点。

 

模拟代码:

//模拟双向链表代码

class Node{
  Node first: //第一个节点  声明方法
  Node last:  //最后一个节点  声明方法
  Node prev:  //上一个节点
  Node next: //下一个节点 声明方法
  Object ele: //节点中的数据 声明方法

  public static void main(String [] Nodetest){
    Node cnode = new Node();
    cnode.next(); //获取下一个节点
    cnode.ele();  //获取当前节点元素。
    cnode.next().ele(); //获取下一个节点中的元素

    cnode.first();  //获取第一个节点
    cnode.last();   //获取最后一个节点
    cnode.prev();    //获取上一个节点
    

}

}

 

基于链表的实现代码:

//基于双向链表的集合
  /**
    *具体操作代码请参见LinkedList源码
    *这里不作具体实现
    */
pub11c class MyLinkedL1st {

      private Node first;//链表的第一个节点
      private Hode last;//链表的最后一个节点
      private int s1ze;//节点的数量
        //链表中的每一个节点
     class Node {

      Node prev;//上一个节点对象

      Node  Next;//下一个节点对象

      Object ele;//当前节点中存储的元素
   
    }
}

 

总结:对于链表操作,无疑是双向链表功能更强大。而双向链表在取头和尾的时候速度更快。

对于链表LinkedList的具体实现,我们仔细读源码可以得出:

删除操作上,链表结构相对于数组结构要更快。

为什么呢?

数组每次进行删除操作都要进行移位与遍历。当某个元素被删除时,后面的元素要向前补位。最后一个元素设为null,

然后再删除最后一个元素所占的内存空间。  

 

链表的删除操作算法分析:

删除(first也可当做current)即第一个节点时,把下一个节点的next赋给第一个节点的next。把第一个节点的prev设为null;

 

删除最后一个节点时,把最后一个节点的prev赋给当前对象的last,再把current节点的上一个(prev)节点的next设为null;

 

删除中间(此处中间节点指将要被删除的节点current)节点时,把current节点的next赋给current节点的上一个节点的next。

再把current节点的prev赋给current节点的下一个节点的prev。

 

下面给出具体实现代码:

 

前文说过,LinkedList在向头和尾添加元素时,性能更优。下面给出具体实现代码及代码分析:

在向头部添加元素时算法实现:

把新增之前第一个节点设为新增节点的next节点,然后把新增节点作为之前第一个节点的上一个节点。(或换种说法:把之前第一个节点的上一个节点作为新增节点),再把新增节点作为第一个节点。而新增节点的prev最好设置为null

 

 

向尾部添加元素算法实现:

把新增节点作为之前最后一个节点的next节点,再把之前最后一个节点作为新增节点的上一个节点。

再把对象的last属性设置为新增节点即可。

 

 

 

      对LinekdList操作的性能分析:

 

     1):增操作:

      双向链表可以直接获取自己的第一个和最后一一个节点,

      如果新增的元素在第一个或最后一 个位置,那么操作只有1次.

 

      2):删除操作(removeFisrt,removelast):

      如果删除第一个元素:操作一一次.如果操作最后一个元素:操作一次如果删除中间的元素:

      找到元素节点平均操作:(1+N)/2次.找到节点之后做删除操作: 1次

     3):查询操作:

      平均:(N+1)/2次

    4):修改操作:

      平均:(N+1)/2+1次
 

 

基于前文(ArrayList性能分析),我们可以得出ArrayList和LinkedList的各自优异之处。

基于数组的列表和基于链表的列表的性能对比:
                                                                    Arraylist:查询,更改较快,新增和刪除较慢
                                                                    Linkeduist查询更改较慢,新增和删除较快

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值