所谓双向链表:

  

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

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

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

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

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

如上图: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. 发布到IIS后 程序乱码

    网站-功能视图-.net全球化 编码设置 请求:utf-8 文件:gb2312 响应:utf-8 响应头:utf-8 可以根据需要自己定义

  2. Fragment实现底部Tab,切换可保存状态

    activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android& ...

  3. oracle nvl()函数在使用中出现的问题

    看一条sql select q.*, r.goods_name from (select nvl(t.goods_code, s.goods_code) goods_code, t.buy_open_ ...

  4. 自定义标签(JSTL)

    自定义标签的步骤: 1.确定需求,如:用<my:date/>输出当前时间 2.编写Java类:需要实现实现接口javax.servlet.jsp.tagext.JspTag 具体的接口为: ...

  5. _CrtMemBlockHeader

    typedef struct _CrtMemBlockHeader{// Pointer to the block allocated just before this one:struct _Crt ...

  6. (原)python使用ctypes调用C/C++接口

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6135514.html 参考网址: https://docs.python.org/2/library/ ...

  7. css应用三

    1. Padding与margin Padding为内边距,padding值会计算在width和height之内.如:width:100px:height:100px:padding:10px:该di ...

  8. 转载:[Java]读取文件方法大全

    转载网址:http://www.cnblogs.com/lovebread/archive/2009/11/23/1609122.html 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取 ...

  9. Nginx的安装及反向代理设置

    因为项目的缘故,接触到了Nginx的安装和反向代理设置,和大家分享下. 一.Nginx的下载.安装cd /homewget http://nginx.org/download/nginx-1.0.5. ...

  10. os8 location authorization 错误.

    今天在XCode6上打开之前写的地图时,给我报这个错 location authorization 去网上查了一番,才知道Xcode6对地图的设置稍有修改 在stackoverflow上找到了答案 i ...