第六章 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;
            }
        }
}
相关推荐
_.Switch10 分钟前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
qq_2546744112 分钟前
工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置
网络
JokerSZ.14 分钟前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
老猿讲编程15 分钟前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk1 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*1 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue1 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man1 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟1 小时前
使用python向钉钉群聊发送消息
java·python·钉钉