JDK学习---深入理解java中的LinkedList

本文参考资料:

 1、《大话数据结构》

 2、http://blog.csdn.net/jzhf2012/article/details/8540543

 3、http://blog.csdn.net/jzhf2012/article/details/8540410

 4、http://www.cnblogs.com/ITtangtang/p/3948610.html

5、http://blog.csdn.net/zw0283/article/details/51132161

  本来在分析完HashSet、HashMap之后,我想紧跟着分析TreeMap以及TreeSet的,但是当我读过源码以后,我就放弃了这个想法。并不是源码有多难,而是TreeMap涉及到的数据结构中的树结构,而我之前一直分析的都是线性结构,而且ArrayList、LinkedList也是线性结构,并且还没有分析。因此,我还是决定按部就班的进行,先把线性表全部分析完了,再去分析TreeMap。

  ArrayList底层源码基本逻辑结构很简单,在《JDK学习---深入理解java中的String》一文中基本已经分析完毕,唯一不同的是String的底层数组不可变,而在ArrayList的底层Object[] 数组中,允许数组增、删、该操作,并且支持数组的动态扩容,这些东西不难,相信读者能很轻松搞明白这些知识,我就不再说明了。

   本文我将重点的说明一下LinkedList知识点,而LinkedList的底层是一个双向链表结构,因此我会在解析源码之前,穿插一些双向链表的知识,然后结合代码进行分析。我不喜欢很空洞的单独去说数据结构,一是因为本人水平有限说不清楚,二是因为我觉得理论需要结合代码,这样分析更加的直观一些。如果读者想要仔细的了解数据结构的知识,可以去找一些书籍详细研读。

  

双向链表

  《JDK学习---深入理解java中的String》一文介绍了数据结构的大体架构,《JDK学习---深入理解java中的HashMap、HashSet底层实现》介绍了线性表的单链表。

    本文将继续介绍数据结构的双向链表。

   双向链表:在单链表的每个节点中,再设置一个指向其前前驱节点的指针域 【DP】

   

既然是双向链表,那么对于链表中的某一个节点(p),它的后继的前驱,以及前驱的后继,其实都是这个节点本身:

p->next->prior = p = p->next-prior

  双链表的插入操作并不复杂,但是顺序很重要,千万不能写错。

  假设,我们现在有一个节点s,它存储的元素为e,现在要将节点s插入到节点p和p->next之间,需要严格的遵守插入的先后顺序,如下图:

s -> prior = p;                    //把p赋值给s的前驱,如图中1
s -> next = p -> next;         //把p -> next 赋值给s的后继,如图中2
p -> next -> prior = s;        //把s 赋值给 p->next的前驱 ,如图中3
p -> next =s;                    //把s 赋值给p 的后继,如图中4

关键在于它们的顺序,由于第2、3步都用到了p->next , 如果第4步先执行,则会使得p->next提前变成了s,使得插入工作完成不了。口诀是:先搞定s的前驱和后继,再搞定后继的前驱,最后解决前节点的后继。

如果插入操作理解了,那么删除操作也就简单了。

p ->prior -> next = p -> next;    //把p ->next赋值给p->prior的后继,如图中1
p ->next -> prior = p ->prior;    //把  p ->prior赋值给p ->next 的前驱,如图中2
free(p);                                     //释放节点p

 

总结:双向链表对于单链表而言,增、删操作要复杂一些,毕竟多了一个prior指针域,所以操作需要格外小心。另外,由于每个节点都需要记录两份指针,空间相对而言也占用略多一些。不过,由于它良好的对称性,使得对某个节点的增、删操作带来了方便。说白了,就是用空间换时间。

时间: 2024-10-22 22:29:48

JDK学习---深入理解java中的LinkedList的相关文章

读深入理解Java中的String(包括JVM)一文总结和提升

读深入理解Java中的String(包括JVM)一文总结和提升 摘要:String作为Java语言中的字符串模拟类,无论是实际的编程工作还是笔试面试过程,都需要我们都String类非常熟悉,对于String类的大部分字符串操作方法,都必须达到熟练运用的程度才行.但是,笔试和面试过程中,面试官往往喜欢问一些String特性相关的题目,来考察面试者对于String基础知识的掌握是否牢固.(本人尚未研读深入理解JVM这本书,分析JVM都是查看网上资料来分析的,若在接下来的内容有分析不到位的地方请见谅和

深入理解Java中的IO

深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: Java IO概要 a.Java IO中常用的类 b.Java流类的类结构图 1.流的概念和作用 2.Java IO所采用的模型  : 3.IO流的分类 4.Java IO流对象 1.输入字节流InputStream 2.输出字节流OutputStream 3.字符输入流Reader 4.字符输出流Write

线程的生命周期 - 理解Java中线程的状态

刚刚开始学cocos2-x,仅仅是按照教程把已经安了一般Android的开发环境的eclipse重新升级到安装好cdt和ndk就花了我几十小时,差点都要放弃了. 参考博客 D:\cocos2d-x\cocos2d-x-2.2.3\cocos2dx\platform\third_party\android\prebuilt 说说大概的过程: 下载ndk插件,ndk包,cdt插件.最开始我按照书上的下载了cocos2d-x 2.0.1,希望跟书上统一起来,这样以后学习的时候可以参考书上的也不会遇到太

Java中的linkedList

Java中的LinkedList实际上是双向链表实现方式 LinkedList<String> list = new LinkedList<String>(); list.add(1); list.add(2) 1->2 这说明默认的add方式是在list的尾部添加了一个元素 list.addLast(3); 1->2->3 list.addFirst(0); 0->1->2->3 list.removeLast(); 0->1->2

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

深刻理解Java中形参与实参,引用与对象的关系

声明:本博客为原创博客,未经允许,不得转载!原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道,在Java中,除了基本数据类型之外,其他的都是引用类型,当它们作为函数参数时,传递的也是引用,通过引用可以改变对象的值,很多人便因此而忽略形参与实参,引用与对象的关系问题.废话不多说,先看下面一个例子: import java.util.*; public class Student { private String

深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/details/26744661),看代码和提问.讨论都更方便. Java中final的作用主要表如今三方面:修饰变量.修饰方法和修饰类.以下就从这两个方面来解说final的作用.在文末从final及类的设计安全性出发,论述了Java中String为何要被设计成不可变类. 1.final修饰变量 fina

理解Java中的弱引用(Weak Reference)

理解Java中的弱引用(Weak Reference) 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出,谢谢大家:) 1. What——什么是弱引用? Java中的弱引用具体指的是java.lang.ref.WeakReference<T>类,我们首先来看一下官方文档对它做的说明: 弱引用对象的存在不会阻止它所指向的对象变被垃圾回收器回收.弱引

深入理解 Java中的 流 (Stream)

首先,流是什么? 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以"流"的方式进行.设备可以是文件,网络,内存等. 流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流. 可以将流想象成一个"水流管道",水流就在这管道中形成了,自然就出现了方向的概念. 当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件.内存或网络等等.