解析LinkedList源码 | Java模拟栈和队列

本文详细介绍了LinkedList的addALL方法,通过索引插入元素的过程,包括检查索引、转换插入元素为数组、遍历插入以及更新链表结构。同时,文章还涵盖了remove方法删除元素的逻辑,set方法替换元素的操作,以及get方法获取元素。此外,文章使用ArrayList模拟了栈和队列的数据结构实现。
摘要由CSDN通过智能技术生成

阅读并且总结linkedList源码内容 增删改查

  • 增--addAll 基于索引将集合中的元素插入到链表某个特定位置的方法

public boolean addAll(int index, Collection<? extends E> c) {  
    checkPositionIndex(index);  //检查指定的索引是不是超过了链表范围
  
    Object[] a = c.toArray();  //将要插入的元素转换为数组
    int numNew = a.length;  //得到想要插入元素的长度/数量
    if (numNew == 0)  //没有要添加的元素,返回false
        return false;  
​
  //如果要插入的是最后一个节点,则该节点的后继节点为null,前驱节点为链表的last,否则找到该索引处的节点及其前驱节点。
    Node<E> pred, succ;  
    if (index == size) {  
        succ = null;  
        pred = last;  
    } else {  
        succ = node(index);  //获取当前索引位置上的node节点
        pred = succ.prev;  //获取当前节点的前驱节点
    }  
  //遍历要插入的元素数组,将每个元素插到链表里面去
    for (Object o : a) {  
        @SuppressWarnings("unchecked") E e = (E) o;//强制转换?  
        Node<E> newNode = new Node<>(pred, e, null);  //创建新的节点,前驱节点为pred,值为e,后继节点为null
        if (pred == null)  //如果前驱节点为空,那么它就成为新节点的第一个节点
            first = newNode;  
        else            pred.next = newNode;  //否则将pred的后继节点指向这个新节点
        pred = newNode;  //又可以把当前插入的这个节点当作下一个要插入元素的前驱节点
    }  
  
    if (succ == null) {  
        last = pred;  
    } else {  
        pred.next = succ;  //  如果succ为null,也就是新加的节点放在了链表的最后一个节点后面,那么last就指向加入的新节点。
        succ.prev = pred;  
​​​​​​​//  如果succ不为null,也就是新加的节点放在了链表中未被替换的位置进行插入,
那么将新增节点与原链表中断开的两个节点重新链接起来,
即前驱节点pred的next指针指向新增节点,新增节点的prev指针指向前驱节点;
后继节点的prev指针指向新增节点,新增节点的next指针指向后继节点。
    } 
  
    size += numNew;  //将newSize的值累加到size的值中,size表示当前LinkedList中元素的个数
    modCount++;  //次数+1
    return true;}//返回true表示插入成功
}
 
  • 删remove

public boolean remove(Object o) {  
    if (o == null) {  //如果待删除对象为空
        for (Node<E> x = first; x != null; x = x.next) {  //遍历,查找匹配项
            if (x.item == null) {  //若当前节点存储的对象也为null
                unlink(x);  //调用这个方法删掉这个节点
                return true;            }  //返回true表示删除成功
        }  
    } else {  //如果删除对象不为null
        for (Node<E> x = first; x != null; x = x.next) {  //遍历,查找匹配的项
            if (o.equals(x.item)) {  //找到了
                unlink(x);  删除节点
                return true;       //true删除成功     }  
        }  
    }  
    return false;  //失败
}
  • 设置set

//set方法用于替换指定位置的元素,参数index为所要替换元素的下标,参数element为替换后的新元素
public E set(int index, E element) {  
​
    checkElementIndex(index);  //检查待替换元素的下标是否合法
    Node<E> x = node(index);  //获取当前位置对应节点
    E oldVal = x.item;  //记录
    x.item = element;  //替换
    return oldVal;  
}
  • 取get

//get返回指定位置的元素
public E get(int index) {  
    checkElementIndex(index);  
    return node(index).item;  
}

利用ArrayList模拟栈和队列

栈:

package com.collection.Static_Queue;  
  
/**  
 * @Author:ZJ-JH  
 * @Description:  
 * @DateTime:2023/6/12 20:28  
 */  
import java.util.NoSuchElementException;  
  
/**  
 * - push: 将元素压入栈顶  
 * - pop: 弹出栈顶元素  
 * - peek: 获取栈顶元素,不弹出  
 * - isEmpty: 判断栈是否为空  
 */  
public class Stack {  
    private Object[] array; // 栈的元素存储在数组中  
    private int capacity; // 栈的最大容量  
    private int top; // 栈顶元素所在位置的下标  
  
    public Stack(int capacity) {  
        this.capacity = capacity;  
        this.array = new Object[capacity];  
        this.top = -1; // 初始化时栈为空  
    }  
  
    /**  
     * 将元素压入栈顶  
     */  
    public void push(Object element) {  
        if (top + 1 >= capacity) {  
            throw new IndexOutOfBoundsException("栈已满");  
        }  
        array[++top] = element; // 将元素放置到栈顶  
    }  
  
    /**  
     * 弹出栈顶元素  
     */  
    public Object pop() {  
        if (isEmpty()) {  
            throw new NoSuchElementException("栈为空");  
        }  
        return array[top--]; // 返回并删除栈顶元素  
    }  
  
    /**  
     * 获取栈顶元素,不弹出  
     */  
    public Object peek() {  
        if (isEmpty()) {  
            throw new NoSuchElementException("栈为空");  
        }  
        return array[top]; // 返回栈顶元素,不删除  
    }  
  
    /**  
     * 判断栈是否为空  
     */  
    public boolean isEmpty() {  
        return top == -1; // 栈为空时栈顶下标为-1  
    }  
}

队列

package com.collection.Static_Queue;  
  
/**  
 * @Author:ZJ-JH  
 * @Description:  
 * @DateTime:2023/6/12 20:27  
 */public class Queue {  
  
    private int front; // 队头指针  
    private int rear; // 队尾指针  
    private int maxSize; // 队列最大长度  
    private Object[] queueArray; // 数据存储数组  
  
    /**  
     * 构造函数,初始化队头、队尾指针和数据存储数组  
     */  
    public Queue(int size) {  
        this.maxSize = size;  
        this.queueArray = new Object[maxSize];  
        this.front = 0;  
        this.rear = -1;  
    }  
  
    /**  
     * 插入元素到队末尾  
     */  
    public void insert(Object element) {  
        if (rear == maxSize - 1) { // 队列已满  
            System.out.println("Queue is full.");  
        } else {  
            queueArray[++rear] = element;  
        }  
    }  
  
    /**  
     * 移除队头元素并返回该元素  
     */  
    public Object remove() {  
        if (front > rear) { // 队列为空  
            System.out.println("Queue is empty.");  
            return null;        } else {  
            return queueArray[front++];  
        }  
    }  
  
    /**  
     * 获取队头元素  
     */  
    public Object peek() {  
        if (front > rear) { // 队列为空  
            System.out.println("Queue is empty.");  
            return null;        } else {  
            return queueArray[front];  
        }  
    }  
  
    /**  
     * 判空  
     */  
    public boolean isEmpty() {  
        return (front > rear);  
    }  
  
    /**  
     * 获取队列长度  
     */  
    public int getSize() {  
        return (rear - front + 1);  
    }  
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值