【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;//🙀
    }
}
相关推荐
极创信息7 分钟前
信创产品认证怎么做?信创产品测试认证的主要流程
java·大数据·数据库·金融·软件工程
SamDeepThinking26 分钟前
并发量就算只有2,该上锁还得上呀
java·后端·架构
Sam_Deep_Thinking42 分钟前
如何让订单系统和营销系统解耦
java·架构·系统架构
lzhdim1 小时前
SQL 入门 12:SQL 视图:创建、修改与可更新视图
java·大数据·服务器·数据库·sql
FQNmxDG4S2 小时前
Maven依赖管理:版本冲突解决与生命周期控制
java·数据库·maven
qeen872 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码2 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
傻瓜搬砖人2 小时前
Spring集成Web环境
java·spring·maven
FQNmxDG4S2 小时前
Java泛型编程:类型擦除与泛型方法的应用场景
java·开发语言·python
我星期八休息3 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表