所谓双向链表:

  

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

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

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

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

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

如上图: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. 东软实训2-在jsp中使用javaBean

    在JSP中可以像使用普通类一样访问JavaBean,在脚本元素中实例化类的对象,调用对象的方法.JSP提供了3个动作元素,和来访问JavaBean. 1.1 动作用于初始化JavaBean,或者定位一 ...

  2. POJ3111 K Best(另类背包+二分+变态精度)

    POJ3111 K Best,看讨论区说数据有点变态,精度要求较高,我就直接把循环写成了100次,6100ms过,(试了一下30,40都会wa,50是4000ms) 第一次在POJ上看到下面这种东西还 ...

  3. Java系列--第四篇 基于Maven的SSME之发送邮件

    在系列第一篇中,使用的是mybatis得到了一个小小的项目,而该项目的用户对象是有邮件地址的,如果按照邮件地址给对方去一封邮件会不会更能体现针对性呢,所以,我在这篇准备加入发送邮件的功能,利用的就是s ...

  4. jQuery1.9(辅助函数)学习之——.serialize();

    $("form").serialize();  返回一个String 描述: 将用作提交的表单元素的值编译成字符串,这个方法不接受任何参数. .serialize(); 方法使用标 ...

  5. web移动开发的小细节(持续添加)

    1.触屏设备上如何去掉数字转化为拨号链接的方法 <meta name=”format-detection” content=”telephone=no” /> telephone=no就禁 ...

  6. Apache主站点配置

    Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd.conf文件中修改. Apache主站点基本配置:ServerRoot "/mnt/software/a ...

  7. 最近写的页面,含有大量的ajax

    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><%@ taglib ur ...

  8. ssm+jsp+自定义标签实现分页,可以通用(前端实现)

    近期做了一些分页方面的开发,大致梳理一下 1 jsp页面上关于分页的代码 <tr> <td colspan="9"> <ule1:pagination ...

  9. UART与USART的区别

    UART与USART都是单片机上的串口通信,他们之间的区别如下: 首先从名字上看: UART:universal asynchronous receiver and transmitter通用异步收/ ...

  10. USART笔记 基于STM32F107VCT6

    USART   通用同步异步收发器 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的 ...