第六章 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;
            }
        }
}
相关推荐
番茄小能手6 分钟前
【全网唯一】C# 纯本地离线文字识别Windows版dll插件
开发语言·c#
敲敲敲-敲代码13 分钟前
【ArcGIS10.2】网络数据集构建---最短路径分析
网络·arcgis
梁诚斌25 分钟前
使用OpenSSL接口读取pem编码格式文件中的证书
开发语言·c++
瓜子三百克43 分钟前
Objective-C 路由表原理详解
开发语言·ios·objective-c
小莫分享1 小时前
github 镜像节点
java
链上Sniper1 小时前
智能合约状态快照技术:实现 EVM 状态的快速同步与回滚
java·大数据·linux·运维·web3·区块链·智能合约
幽蓝计划1 小时前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
伍哥的传说1 小时前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
缘来是庄2 小时前
设计模式之建造者模式
java·设计模式·建造者模式
小湘西2 小时前
Apache HttpClient 的请求模型和 I/O 类型
java·http·apache