【Java】/* 双向链表 - 底层实现 */

【难点】:remove、removeAllKey

一、IList

java 复制代码
package bagfive;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: tangyuxiu
 * Date: 2024-08-21
 * Time: 20:30
 */
public interface IList<E> {
    //头插法
    void addFirst(E data);
    //尾插法
    void addLast(E data);
    //任意位置插入,第一个数据节点为0号下标
    void addIndex(int pos,E data);
    //查找是否包含关键字key是否在单链表当中
    boolean contains(E key);
    //删除第一次出现关键字为key的节点
    void remove(E key);
    //删除所有值为key的节点
    void removeAllKey(E key);
    //得到单链表的长度
    int size();
    void display();
    void clear();
}

二、MyLinkedList

java 复制代码
package bagfive;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: tangyuxiu
 * Date: 2024-08-21
 * Time: 20:30
 */
public class MyLinkedList<E> implements IList<E> {

    /* 使用内部类定义双向链表节点 */
    private static class ListNode<E> {
        E val;
        ListNode<E> prev;
        ListNode<E> next;

        public ListNode(E val) {
            this.val = val;
        }
    }

    private ListNode<E> head;
    private ListNode<E> last;

    @Override
    public void addFirst(E data) {
        ListNode<E> newNode = new ListNode<>(data);
        //1. 如果链表为null
        if (this.head == null) {
            this.head = this.last = newNode;
            return;
        }
        //2. 链表不为null
        newNode.next = this.head;
        this.head.prev = newNode;
        this.head = newNode;
    }

    @Override
    public void addLast(E data) {
        ListNode<E> newNode = new ListNode<>(data);
        //1. 如果链表为null
        if (this.head == null) {
            this.head = this.last = newNode;
            return;
        }
        //2. 链表不为null
        this.last.next = newNode;
        newNode.prev = this.last;
        this.last = newNode;
    }

    /* 判断add的位置是否合法 */
    private boolean addIndexIsLegal(int pos) {
        if (pos < 0 || pos > this.size()) {
            return false;
        }
        return true;
    }

    @Override
    public void addIndex(int pos, E data) {
        //1. 判断pos位置是否合法
        if (!this.addIndexIsLegal(pos)) {
            return;
        }
        //2. pos == 0
        if (pos == 0) {
            this.addFirst(data);
            return;
        }
        //3. pos == size()
        if (pos == this.size()) {
            this.addLast(data);
            return;
        }
        //4. 其他位置,不需要找前驱节点了
        ListNode<E> newNode = new ListNode<>(data);
        ListNode<E> cur = this.head;
        for (int i = 0; i < pos; i++) {
            cur = cur.next;
        }
        newNode.next = cur;
        cur.prev.next = newNode;
        newNode.prev = cur.prev;
        cur.prev = newNode;
    }

    @Override
    public boolean contains(E key) {
        ListNode<E> cur = this.head;
        while (cur != null) {
            if (cur.val.equals(key)) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    @Override
    public void remove(E key) {
        // 头,任意,尾 (链表为null进不去循环)
        ListNode<E> del = this.head;
        while (del != null) {
            if (del.val.equals(key)) {
                if (this.head == del) {//如果为头节点
                    if (this.head.next == null) {//如果为头节点,且链表只有一个节点
                        this.head = this.last = null;
                    } else {
                        this.head = this.head.next;
                        this.head.prev = null;
                    }
                } else {
                    if (this.last == del) {//如果为尾节点
                        this.last = this.last.prev;
                        this.last.next = null;
                    } else {//其他位置
                        del.prev.next = del.next;
                        del.next.prev = del.prev;
                    }
                }
                return;
            }
            del = del.next;
        }
    }

    @Override
    public void removeAllKey(E key) {
        // 头,只一个节点,任意,尾 (链表为null进不去循环)
        ListNode<E> del = this.head;
        while (del != null) {
            if (del.val.equals(key)) {
                if (this.head == del) {//如果为头节点
                    if (this.head.next == null) {//如果为头节点,且链表只有一个节点
                        this.head = this.last = null;
                    } else {
                        this.head = this.head.next;
                        this.head.prev = null;
                    }
                } else {
                    if (this.last == del) {//如果为尾节点
                        this.last = this.last.prev;
                        this.last.next = null;
                    } else {
                        del.prev.next = del.next;//其他位置
                        del.next.prev = del.prev;
                    }
                }
            }
            del = del.next;
        }
    }

    @Override
    public int size() {
        int count = 0;
        ListNode<E> cur = this.head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    @Override
    public void display() {
        ListNode<E> cur = this.head;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        ListNode<E> cur = this.head;
        while (cur != null) {
            cur.val = null;
            cur = cur.next;
        }
        this.head = this.last = null;//🙀
    }
}
相关推荐
天涯过客TYGK几秒前
unity console日志双击响应事件扩展
java·unity·junit
Root06241 分钟前
【笔记】记一次easyExcel中注解ExcelProperty映射字段赋值无效问题
java·开发语言·笔记
一个努力学习的小男孩3 分钟前
java环境部署
java·开发语言
轻浮j5 分钟前
ReentrantLock原理(源码解析)
java
A boy CDEF girl9 分钟前
【JavaEE】阻塞队列
java·开发语言·java-ee
WanderInk10 分钟前
JavaWeb CRUD 与分页系统架构学习教程
java·后端·架构
_Djhhh13 分钟前
权限系统设计方案实践(Spring Security + RBAC 模型)
java·linux·数据库·spring
天上掉下来个程小白32 分钟前
开发环境搭建-06.后端环境搭建-前后端联调-Nginx反向代理和负载均衡概念
java·运维·spring boot·后端·nginx·负载均衡·苍穹外卖
试着生存35 分钟前
java根据List<Object>中的某个属性排序(数据极少,顺序固定)
java·python·list
_星辰大海乀36 分钟前
LinkedList 双向链表
java·数据结构·链表·list·idea