所谓双向链表:

  

(由此图可见老夫深厚的画功)

链表,就是由一个一个的节点连接组成。

在这里,每一个节点都是由三部分组成:上一个节点、当前节点的元素、下一个节点

当链表中只有一个节点的时候,这个节点指向的上一个节点是空的,下一个节点也是空的

当有多个节点的时候,第一个节点的上一个节点是空的,最后一个节点的下一个节点也是空的。

如上图:A节点的下一个节点指向了B节点,B节点的上一个节点指向了A节点

不说了...鉴于本人表达能力有限...直接上代码吧...

 public class MyLinkedList {
     /*第一个节点*/
     private Node first;
     /*最后一个节点*/
     private Node last;
     /*大小*/
     private int size;
     /**
      * 获取这个链表的大小(元素的个数)
      * @return
      */
     public int size(){
         return size;
     }
     /**
      * 这个方法是从LinkedList.node(index)方法中复制过来的,稍加修改
      * 用于返回指点下标处的节点
      * @return
      */
     private Node node(int index){
         /*
          * 打个比方:
          * size = 6;
          * size >> 1 = 3
          * 如果index小于3的话,就从第一个找到最后一个
          * 如果index大于3的话,就从最后一个找到第一个
          * 下面代码亦是如此
          */
         if (index < (size >> 1)) {
             Node x = first;
             for (int i = 0; i < index; i++)
                 x = x.next;
             return x;
         } else {
             Node x = last;
             for (int i = size - 1; i > index; i--)
                 x = x.prev;
             return x;
         }
     }
     /**
      * 增加一个节点
      * @param obj 要增加的元素
      */
     public void add(Object obj){
         Node temp = new Node();//新的节点
         /*新节点的元素赋值*/
         temp.element = obj;

         if (first==null) {//如果第一个节点是空的,那就是没有节点
             //这个节点既然是第一个节点,所以节点的prev点和next都是空的,所以,不用赋值
             //同理,这个新插入的节点是第一个,也是最后一个
             first = temp;
             last = temp;
         }else {//否则,那就意味着这个节点不是空的。
             //新节点的prev就是在这个节点插入前的最后一个节点
             temp.prev = last;
             //而插入前的最后一个节点的next就是这个新的节点了
             //这样,就会形成一条链:a的下一个是b,b的上一个是a,a的下一个是b......
             last.next = temp;
             //最后,新的节点就是最后一个节点了
             last = temp;
         }
         //插入成功size++;
         size++;
     }
     /**
      * 增加一个节点,指定位置
      * @param index
      * @param obj
      */
     public void add(int index, Object obj){
         Node temp = node(index);//得到的节点
         Node newNode = new Node();//新的节点
         newNode.element = obj;

         if (temp!=null) {//如果得到的指定节点不是空的话
             //得到temp的上一个节点
             Node tempPrev = temp.prev;

             //tempPrev的下一个节点赋值为newNode
             tempPrev.next = newNode;
             //同时,newNode的上一个节点赋值为tempPrev
             newNode.prev = tempPrev;

             //然后newNode的下一个节点便是这个一开始就指定的temp节点
             newNode.next = temp;
             //temp的上一个节点赋值为newNode
             //这样在指定元素之前插入了一个新的元素
             temp.prev = newNode;
         }
         size++;
     }
     /**
      * 删除
      * @param index
      */
     public void remove(int index){
         /*
          * 删除...
          * 有 a b c三个元素
          * a的下一个节点是b b的下一个节点是c
          * c的上一个节点是b b的上一个节点是a
          * --
          * 比如删除了b
          * 那就要把a 和 c 连接起来。
          *
          * 连接好了后,就是:
          * a 下一个节点是 c
          * c 上一个节点是 a
          *
          */

         Node temp = node(index);//得到指定下标的元素
         if (temp!=null) {
             /*

             //得到temp的上一个节点
             Node tempPrev = temp.prev;
             //得到temp的下一个节点
             Node tempNext = temp.next;
             //tempPrev的下一个节点是tempNext
             tempPrev.next = tempNext;
             //而tempNext的上一个节点就是tempPrev
             tempNext.prev = tempPrev;

             */

             //temp的上一个节点的下一个节点就是temp的下一个节点
             temp.prev.next = temp.next;
             //temp的下一个节点的上一个节点就是temp的上一个节点
             temp.next.prev = temp.prev;
         }
         size--;
     }
     /**
      * 根据下标获取元素
      * @param index 元素的索引
      * @return
      */
     public Object get(int index){
         return node(index).element;//得到指定节点的元素
     }
     /*------------------------------------------------------------*/
     public static void main(String[] args) {
         MyLinkedList list = new MyLinkedList();
         list.add("a");
         list.add("b");
         list.add(1,"B");
         list.remove(1);
         System.out.println(list.get(1));
         System.out.println("当前链表的大小:"+list.size());
     }
 }
 /**
  * 节点类
  */
 class Node{
     /*
      * 表示上一个节点
      * 所以使用节点类型
      */
     Node prev;
     /*表示下一个节点*/
     Node next;
     /*当前节点的元素*/
     Object element;

     public Node() {
     }

     public Node(Node prev, Node next, Object element) {
         this.prev = prev;
         this.next = next;
         this.element = element;
     }

 }

LinkedList : 双向链表与实现的更多相关文章

  1. JDK1.8 LinkedList双向链表源码

    序言 LinkedList是一个双向链表 也就是说list中的每个元素,在存储自身值之外,还 额外存储了其前一个和后一个元素的地址,所以也就可以很方便地根据当前元素获取到其前后的元素 链表的尾部元素的 ...

  2. JAVA数据结构--LinkedList双向链表

    链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括两个部分: ...

  3. Java 集合深入理解(11):LinkedList

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情鱼肚白,来学学 LinkedList 吧! 日常开发中,保存一组数据使用的最多的就是 ArrayList, 其次就 ...

  4. LinkedList的自定义实现

    一.背景 LinkedList双向链表: 代码: Node.java: package com.cy.collection; public class Node { Node previous; // ...

  5. 深入理解java集合框架之---------LinkedList

    日常开发中,保存一组数据使用的最多的就是 ArrayList, 其次就是 LinkedList 了. 我们知道 ArrayList 是以数组实现的,遍历时很快,但是插入.删除时都需要移动后面的元素,效 ...

  6. LinkedList 基本示例及源码解析

    目录 一.JavaDoc 简介 二.LinkedList 继承接口和实现类介绍 三.LinkedList 基本方法介绍 四.LinkedList 基本方法使用 五.LinkedList 内部结构以及基 ...

  7. Java集合 LinkedList的原理及使用

    Java集合 LinkedList的原理及使用 LinkedList和ArrayList一样是集合List的实现类,虽然较之ArrayList,其使用场景并不多,但同样有用到的时候,那么接下来,我们来 ...

  8. List集合总结,对比分析ArrayList,Vector,LinkedList

    前面已经写了三篇关于Java集合的文章,包括: Java集合 ArrayList原理及使用 再说Java集合,subList之于ArrayList Java集合 LinkedList的原理及使用 关于 ...

  9. 源码分析(5)-ArrayList、Vector和LinkedList(JDK1.8)

    一.概述 1.线程安全:ArrayList和LinkedList非线程安全的.Vector线程安全的. 2.底层数据结构:ArrayList和Vector底层数据结构是数组:LinkedList双向链 ...

随机推荐

  1. jQuery选择器 之详述

    jQuery选择器 一. 单词小计 Pervious 上一页sibling  同级first  第一last  最后not  不 Even  偶数    odd  奇数 header  页眉 一.jQ ...

  2. Mongodb基本操作之.net

    1.下载官方for C#驱动 2.导入2个dll文件 3.连接字符串 <add key="MongoConn" value="mongodb://127.0.0.1 ...

  3. php连接mysql的一些方法总结

    为了能让PHP连接MSSQL,系统需要安装MSSQL,PHP,且在PHP.ini中的配置中,将       ;extension=php_mssql.dll前面的;去掉 1.连接MSSQL       ...

  4. CSS学习笔记总结和技巧

    跟叶老师说项目,他叫我写一个静态首页,看起来挺简单的,但是下手才发现在真的不会怎么下手啊,什么模型啊模块啊都不懂,写毛线啊!! 如图:页面下拉还有侧栏,中间内容等. 可是答应跟老师做了,不能怂啊,于是 ...

  5. spring 学习 AOP和IOC

    自11开始接触三大框架,至今已俞5载, 当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了 spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转) 1.其中, ...

  6. Cocos2DX新手入门笔记索引

    01--从根源种子CCNode说起 02—从Cocos2DX视角看游戏组成 03--理解HelloWorld结构 04--简单菜单使用 05--简单场景切换与精灵创建 06--触摸事件响应 07--动 ...

  7. Python核心编程(第八章)--条件和循环

    如果一个复合语句(if子句,while或for循环)的代码仅仅包含一行代码,可以和前面的语句写在同一行上:   elif语句(else-if) 条件表达式(三元操作符) X if C else Y 计 ...

  8. Python函数小结(1)--参数类型(*, ** 的区别), 闭包

    刚开始学习python,python相对于java确实要简洁易用得多.内存回收类似hotspot的可达性分析, 不可变对象也如同java得Integer类型,with函数类似新版本C++的特性,总体来 ...

  9. C程序设计语言练习题1-3

    练习1-3 修改温度转换程序,使之能在转换表的顶部打印一个标题. 代码如下: #include <stdio.h> // 包含标准库的信息. int main() // 定义名为main的 ...

  10. Java学习笔记--NIO

    参考资料:http://ifeve.com/buffers/ BIO/NIO/AIO的区别联系 http://stevex.blog.51cto.com/4300375/1284437http://w ...