第六章 7.0 LinkList

链表

一个节点分两个部分,一部分存数据,一部分存下一个节点的内存地址

单项链表伪代码

LinkedList

  • LInkedList是一个双向链表
  • 源码分析:属性分析、构造方法分析、添加元素、修改元素、插入元素、删除元素
java 复制代码
public class LinkelisrTest01 {
    public static void main(String[] args) {
        //双链表
        //空构造方法
        LinkedList<String> list1 = new LinkedList<>();
        list1.add("1");
        list1.add("2");
        list1.add("3");
        list1.add("4");

        list1.set(1,"110");

        list1.remove(1);

        String s = list1.get(list1.size() - 1);
        System.out.println(s);
    }
}

属性分析

java 复制代码
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     * Pointer to first node.
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     */
    transient Node<E> last;

存有头节点,尾节点,和链表的总节点数是一个双向链表

Node<E>是一个类,Node节点的含义,item保存的数据,next下一个节点的引用

java 复制代码
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;
}

构造方法

java 复制代码
public LinkedList() {
    }

add()方法

先创建一个节点对象Node(),记录该节点的内存地址,前一个节点对象存储新节点的内存地址,新节点的prev存储前节点的内存地址,next存储后一个节点的内存地址,这样就增添了元素。

源码分析:

l保存的是上一个节点,new了一个新的节点,保存了l的内存地址和所要存储的数据,判断上一个节点是否位空,如果是空的话,则直接是头节点(注意first是一个头节点类,存储着size),如果不是,存储数量加1。

add(data,index)方法

源码分析

node(index):根据下标找到节点

new一个新的节点,before保存新节点的地址,新节点保存before的地址,next保存下一个节点的地址。

set()方法

node(index)找到元素,直接改就行.

剩余两个类似,可以查看源码

手写单向链表

java 复制代码
/**
 * 自定义单项链表
 */
public class Test01<E> {
    //首先,有存储数据数量的方法
    private int size;
    private Node<E> first;

    /**
     * 无参构造方法
     */
    public Test01() {
    }
    //获取集合中元素的个数
    public int size(){
        return size;
    }

    /**
     * 添加元素到末尾
     * @param data
     */
    public void add(E data) {
        if (first == null) {
            first = new Node<>(data, null);
            size++;
            return;
        } else {
            //找到末尾节点
            Node<E> last = findLast();
            last.next = new Node<>(data, null);
            size++;
        }
    }

    /**
     * 寻找最后一个节点的方法
     * @return
     */
    private Node<E> findLast() {
        if (first == null) {
            return null;
        } else {
            //假设第一个节点就是最后一个节点
            Node<E> last = first;
            while(last.next !=null){
                last = last.next;
            }
            return last;
        }
    }

    /**
     * 添加元素到指定的索引处
     * @param index
     * @param data
     */
   public void add ( int index, E data){
        //创建新的节点对象
        Node<E> node = new Node<>(data,null);
        //找到对应下标节点
        Node<E> a = node(index);
        //新节点node next存储当前节点;
        node.next = a;
        //寻找当前下标节点的上一个节点
        Node<E> prev = node(index -1 );
        //上一个节点next值等于当前节点
        prev.next = node;
    }

    /**
     * 寻找指定节点的方法
     * @param index
     * @return
     */
    private Node<E> node(int index) {
        Node<E> next =first;
        for (int i=0;i<index;i++){
            next = next.next;
        }
        return next;
    }

    /**
     * 删除元素
     * @param index
     */
   public void remove (int index){
       Node<E> node = node(index);
       Node<E> prev = node(index-1);
       Node<E> next = node(index+1);
       prev.next = next;

    }

    /**
     * 修改元素
     * @param index
     * @param data
     */
   public void set ( int index, E data){
        //寻找对应下标的node
       Node<E> node = node(index);
       node.item = data;

    }

    /**
     * 查找元素
     * @param index
     * @return
     */
   public Node<E> get ( int index){
       Node<E> node = node(index);
            return node;
        }

    /**
     * 节点内部类
      * @param <E>
     */
   private static class Node<E> {
            E item; //存储的数据值
            Node<E> next; //下一个节点

            public Node(E item, Node next) {
                this.item = item;
                this.next = next;
            }
        }
}
相关推荐
武子康15 分钟前
Java-71 深入浅出 RPC Dubbo 上手 父工程配置编写 附详细POM与代码
java·分布式·程序人生·spring·微服务·rpc·dubbo
艾莉丝努力练剑1 小时前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
Fireworkitte1 小时前
gRPC和http长轮询
网络·网络协议·http
LuLaLuLaLeLLLLLL2 小时前
RPC 框架学习笔记
网络·网络协议·rpc
武子康2 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
_殊途3 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
冰橙子id3 小时前
linux-远程访问管理(sshd,scp,sftp)
linux·网络·ssh
椰椰椰耶4 小时前
【Spring】拦截器详解
java·后端·spring
没有bug.的程序员5 小时前
JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》
java·面试·mybatis
倔强青铜35 小时前
苦练Python第18天:Python异常处理锦囊
开发语言·python