链式存储方式线性表之LinkedList源码解析

线性表:顺序存储结构和链式存储结构
链式存储结构的优缺点:

  • 优点:删除插入效率高
  • 缺点:查询效率高


    image.png

    image.png

    循环列表:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相连的单链表称为单循环链表,简称循环链表


    image.png

    双向循环列表:双向循环链表是单向循环链表的每个结点中,再设置一个指向其前驱结点的指针域
    image.png

    对于空的双向循环列表
    image.png

    双向循环列表插入


    image.png

    双向列表的删除
    image.png

LinkedList源码解析:双向列表而非循环列表

参数和构造函数源码解析

transient Link<E> voidLink;//这个参数代表头指针

  private static final class Link<ET> {
        ET data;//每个的数据

        Link<ET> previous, next;//前一个指针和下一个指针

        Link(ET o, Link<ET> p, Link<ET> n) {
            data = o;
            previous = p;
            next = n;
        }
    }

迭代器源码解析

参数和构造函数源码解析

  private static final class LinkIterator<ET> implements ListIterator<ET> {
       final LinkedList<ET> list;
        Link<ET> link, lastLink;//当前节点和最后一个节点
 //双向列表
  LinkIterator(LinkedList<ET> object, int location) {
            list = object;
            expectedModCount = list.modCount;//修改次数赋值
            if (location >= 0 && location <= list.size) {
               //设置当前节点为头指针
                link = list.voidLink;
               //二分查找
                if (location < list.size / 2) {
                    for (pos = -1; pos + 1 < location; pos++) {
                        //当前节点为下一个节点
                       //循序查找
                        link = link.next;
                    }
                } else {
                    for (pos = list.size; pos >= location; pos--) {
                          //倒序查找
                        link = link.previous;
                    }
                }
            } else {
                throw new IndexOutOfBoundsException();
            }
        }
}

add添加源码解析,所以add并不是添加到尾部

public void add(ET object) {
          if (expectedModCount == list.modCount) {
               //指向下一个节点
               //link代表01   link.next代表原来指向的02,现在插入03
               Link<ET> next = link.next;//原本指向的下一个节点
             //添加对象新建一个节点     link为前一个节点,next为下一个节点
              Link<ET> newLink = new Link<ET>(object, link, next);
              link.next = newLink;//当前01的指向为03
              next.previous = newLink;//02的前一个指向03
              link = newLink;//下一个节点则为03
              lastLink = null;//最后一个为空
              pos++;
              expectedModCount++;
              list.size++;
              list.modCount++;
          } else {
              throw new ConcurrentModificationException();
          }
      }

添加头部源码解析

    public void addFirst(E object) {
        addFirstImpl(object);
    }
    private boolean addFirstImpl(E object) {
        Link<E> oldFirst = voidLink.next;//原本指向01
        Link<E> newLink = new Link<E>(object, voidLink, oldFirst);//object新建一个指针对象
        voidLink.next = newLink;
        oldFirst.previous = newLink;
        size++;
        modCount++;
        return true;
    }

添加尾部源码解析

 public void addLast(E object) {
        addLastImpl(object);
    }

private boolean addLastImpl(E object) { 
          //在构造函数的时候我们进行了二分查找,此时是倒查找
        Link<E> oldLast = voidLink.previous;//此时指向的是最后一个指针
        Link<E> newLink = new Link<E>(object, oldLast, voidLink);
        voidLink.previous = newLink;
        oldLast.next = newLink;
        size++;
        modCount++;
        return true;
    }

是否有上下指针

 public boolean hasNext() { 
           return link.next != list.voidLink;//不等于头指针就代表有下个指针
}
public boolean hasPrevious() {
           return link != list.voidLink;
}

next源码解析

       public ET next() {
            if (expectedModCount == list.modCount) {
                LinkedList.Link<ET> next = link.next;
                if (next != list.voidLink) {//代表有下一个
                    lastLink = link = next;//默认这是最后一个指针和正处于的指针都为下一个指向的指针
                    pos++;
                    return link.data;//返回数据
                }
                throw new NoSuchElementException();
            }
            throw new ConcurrentModificationException();
        }

移除源码解析

public void remove() {
           if (expectedModCount == list.modCount) {
               if (lastLink != null) {
                    Link<ET> next = lastLink.next; //next 最后节点下一个指针03
                   Link<ET> previous = lastLink.previous;//previous  最后节点上一个指针01
                   next.previous = previous;// next.previous为03的前一个指针指向01
                   previous.next = next;// previous.next 01的下一个指针指向03
                   if (lastLink == link) {
                       pos--;
                   }
                   link = previous;
                   lastLink = null;
                   expectedModCount++;
                   list.size--;
                   list.modCount++;
               } else {
                   throw new IllegalStateException();
               }
           } else {
               throw new ConcurrentModificationException();
           }
       }

补充一下,简单看下LinkedHashMap双向循环列表的add源码


 @Override void addNewEntry(K key, V value, int hash, int index) {
        LinkedEntry<K, V> header = this.header;//首先获取头部

        LinkedEntry<K, V> eldest = header.nxt;
        if (eldest != header && removeEldestEntry(eldest)) {
            remove(eldest.key);
        }
        LinkedEntry<K, V> oldTail = header.prv;//头部指向前一个指针即最后一个元素
        LinkedEntry<K, V> newTail = new LinkedEntry<K,V>(
                key, value, hash, table[index], header, oldTail);//new一个新的指针
           //头部前一个指向新的指针,原本最后一个元素的下一个指针指向新的指针
        table[index] = oldTail.nxt = header.prv = newTail;
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容