集合学习3——LinkedList

1 LinkedList的数据结构

LinkedList底层维护了一个双向链表。根据下图所知,LinkedList集合中有两个属性,first和last分别指向首节点和尾节点。每个节点对象(Node对象),里面又维护了prev、next、item三个属性,其中prev指向前一个节点,next指向后一个节点,最终实现双向链表。这样也意味着,LinkedList中的元素的增加与删除的效率高于ArrayList【底层通过数组结构实现】。仅仅只需要修改节点prev、next的指向即可。
在这里插入图片描述

节点Node对象

    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

2 自定义实现双向节点

public class MyLinkedList {

    public static void main(String[] args) {
        Node node1=new Node("1");
        Node node2=new Node("2");
        Node node3=new Node("3");

        node1.next=node2;
        node2.next=node3;

        node3.prev=node2;
        node2.prev=node1;

        Node first=node1;
        Node last=node3;

        //从头进行遍历
        System.out.println("从头进行遍历");
        while (first!=null){

            System.out.println(first);
            //移动指针到下一个节点
            first=first.next;
        }


        //从尾进行遍历
        System.out.println("从尾进行遍历");
        while (last!=null){

            System.out.println(last);
            //移动指针到下一个节点
            last=last.prev;
        }


        //插入新的节点 node1 new node2
        Node newNode=new Node("new");

        node1.next=newNode;
        newNode.next=node2;

        node2.prev=newNode;
        newNode.prev=node1;

        //首节点重新置位
        first=node1;

        //插入节点后从新进行遍历
        System.out.println("插入节点后重新进行遍历");
        while (first!=null){

            System.out.println(first);
            //移动指针到下一个节点
            first=first.next;
        }

        //删除节点 node3
        node2.next=last;
        //首节点重新置位
        first=node1;
        //插入节点后从新进行遍历
        System.out.println("删除节点 node3重新进行遍历");
        while (first!=null){

            System.out.println(first);
            //移动指针到下一个节点
            first=first.next;
        }
    }

}

class  Node<T>{

    //结点内容
    T item;
    //指向前一个节点
    Node prev;
    //指向下一个节点
    Node next;


    Node(T item){
        this.item=item;
    }


    @Override
    public String toString() {
        return "Node{" +
                "item=" + item +
                '}';
    }
}

运行输出如下

从头进行遍历
Node{item=1}
Node{item=2}
Node{item=3}
从尾进行遍历
Node{item=3}
Node{item=2}
Node{item=1}
插入节点后重新进行遍历
Node{item=1}
Node{item=new}
Node{item=2}
Node{item=3}
删除节点 node3重新进行遍历
Node{item=1}
Node{item=new}
Node{item=2}

3 LinkedList源码分析

  public static void main(String[] args) {

        //构造函数
        //  public LinkedList() {} 此时 first与last 属性的值为null,
        LinkedList list = new LinkedList();

        //向尾部链接新的元素
        //   void linkLast(E e) {
        //        final Node<E> l = last;
        //        final Node<E> newNode = new Node<>(l, e, null);
        //        last = newNode;
        //        if (l == null)
        //            first = newNode;
        //        else
        //            l.next = newNode;
        //        size++; //链表长度加一
        //        modCount++; //修改链表对象变更的次数
        //    }
        list.add(1);
        list.add(2);
        list.add(3);



        删除元素【删除第一个元素】 f=first
        //    private E unlinkFirst(Node<E> f) {
        //        final E element = f.item;
        //        final Node<E> next = f.next; //next节点指向节点2
        //        f.item = null;
        //        f.next = null; //断开原来的首节点与下一个节点间的关系
        //        first = next; //首节点指向节点2
        //        if (next == null)
        //            last = null;
        //        else
        //            next.prev = null; 首节点的前一个节点为空
        //        size--; //节点长度减一
        //        modCount++; //
        //        return element; 返回删除的节点内容值 即为一
        //    }
        list.remove();

        System.out.println(list);
    }

list.add(1)执行时源码分析
在这里插入图片描述

list.add(2)执行时源码分析
在这里插入图片描述
list.remove();执行时源码分析

在这里插入图片描述

分析源码可知,LinkedList中元素的新增与删除只要是变动节点间的prev、next之间的指向。在调试源码的过程中,可以加深对LinkedList方法的理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值