第六章 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;
            }
        }
}
相关推荐
Q_19284999068 分钟前
基于Spring Boot的建材租赁系统
java·spring boot·后端
鲨鱼辣椒不吃辣c9 分钟前
拦截器魔法:Spring MVC中的防重放守护者
java·spring·mvc
winks316 分钟前
Spring Task的使用
java·后端·spring
云空21 分钟前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
秋意钟26 分钟前
Spring新版本
java·后端·spring
椰椰椰耶28 分钟前
【文档搜索引擎】缓冲区优化和索引模块小结
java·spring·搜索引擎
mubeibeinv30 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
青莳吖31 分钟前
Java通过Map实现与SQL中的group by相同的逻辑
java·开发语言·sql
Buleall38 分钟前
期末考学C
java·开发语言
重生之绝世牛码40 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式